Thread: DLL Interface Oddity

  1. #1
    Registered User Adventus's Avatar
    Join Date
    May 2007
    Location
    Canberra, Australia
    Posts
    4

    Arrow DLL Interface Oddity

    For a few days now i've been investigating how to best send data structures (specifically STL vectors) from a c++ DLL to some indie gamedev software based on Delphi (which i dont have internal access to). I've narrowed it down to two options, either i simply call the DLL multiple times to recieve one number at a time and incur some nasty overhead, or I send an appropiately formatted string (convert 16bit ints to 2x 8bit chars) containing the vector.

    The problem is that when it tries to send a number below 256, the string length is apparently only 1 instead of being 2 with a zero character. At first i thought it was the signed 16bit number messing with the bitwise operators.... but beyond that i've really got no idea. Is it possible that im inserting a null character as opposed to a zero? How would i stop this?

    As i test i wrote the DLL below:
    Code:
    #include <windows.h>
    #include <string>
    #define export extern "C" __declspec(dllexport) __stdcall
    
    using namespace std;
    
    string str = "";
    
    export const char* send_ds(){
    	str = "";
    	unsigned __int16 j0 = 1;
    	__int8 j1 = ((j0<<8)>>8);
    	__int8 j2 = (j0>>8);
    	str += char(j1);
    	str += char(j2);
    	return (str.c_str());
    	}
    		
    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){
        switch (fdwReason){
            case DLL_PROCESS_ATTACH: {break;}
            case DLL_PROCESS_DETACH: {break;}
            case DLL_THREAD_ATTACH: {break;}
            case DLL_THREAD_DETACH: {break;}
        	}
        return TRUE;
        }
    PS: Sorry for the sloppy coding format, i've never had any formal training, so i kinda just made it up as i went along. Also, Im using Dev-C++ and Mingw if thats of any importance....
    Last edited by Adventus; 05-31-2007 at 08:58 PM.

  2. #2
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >Is it possible that im inserting a null character as opposed to a zero?
    That's what it looks like is happening. One idea is to convert the number to a string first:
    Code:
    #include <sstream>
    .
    .
    	int j0 = 1;
    	std::ostringstream converter;
    
    	converter << j0;
    
    	return converter.str().c_str();

  3. #3
    Registered User Adventus's Avatar
    Join Date
    May 2007
    Location
    Canberra, Australia
    Posts
    4
    Ok, yea im pretty sure im inserting a null character. I tested it by putting this after the str+= char(j0) bit:
    Code:
    str += "hmmmm";
    .... and it still resulted in a string length of 1. I guess its pretty obvious if you know that char(0) = Null character.... (which i happened not to know, by the way)

    That's what it looks like is happening. One idea is to convert the number to a string first
    That would introduce a bit too much overhead for my liking especially since it would require reconversion at the other end. I think my best possibility is simply adding a 1 at the end of each 8bit value, which will reduce it to a 14bit number.... but it'll still be fast enough. Any other ideas?

  4. #4
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Are you expecting a string at the other end? It sounds like that's the case, becasue otherwise the null character wouldn't even be a problem.

    So based on the assumption you are looking for a string at the other end, converting the number to a string makes sense. But I'm likely missing something. But you can convert any number the fits in an int (or bigger if you use a larger integer type). You could even send a group of numbers separated by spaces or commas:
    Code:
    int a = 111111;
    int b = 222222;
    converter << a << " " << b;
    Last edited by swoopy; 05-31-2007 at 11:25 PM.

  5. #5
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    If you're just expecting an array of numbers at the other end (not a string), then the null character won't be a problem. As you said it's the same as sending the number zero. So at the other end, it's interpreted as the number 0. The issue comes into play with strings.

  6. #6
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Here's another suggestion: send a second parameter which contains the length of the data:
    Code:
    export const char* send_ds(int *length){
    	str = "";
    	unsigned __int16 j0 = 1;
    	__int8 j1 = ((j0<<8)>>8);
    	__int8 j2 = (j0>>8);
    	str += char(j1);
    	str += char(j2);
    	*length = str.length();
    	return (str.c_str());
    	}

  7. #7
    Registered User Adventus's Avatar
    Join Date
    May 2007
    Location
    Canberra, Australia
    Posts
    4
    Yea, im just trying to send an array of numbers. I think the recieving programs a bit wacky (really limited anyway), when i pass the string it regards it as a string instead of a char array, and wont let me access the numbers after the null.

    Anyway, i have somewhat solved this problem by restricting the 16bit numbers to 14bits (not really a huge worry) and adding an unused 0000001 at the end of characters so it doesnt null the string. Thanks for your help, it definitely been a learning experience for me.

    Heres the modified function:
    Code:
    export const char* send_ds(){
    	str = "";
    	unsigned __int16 j0 = 16127;
    	__int8 j1 = ((j0<<9)>>8)+1;
    	__int8 j2 = (((j0>>7)<<9)>>8)+1;
    	str += char(j1);
    	str += char(j2);
    	return (str.c_str());
    	}
    Any other ideas?

  8. #8
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    when i pass the string it regards it as a string instead of a char array, and wont let me access the numbers after the null.
    That being the case, I guess passing the length as another parameter isn't going to help. But it looks like you've found something which will work. Perhaps you can find a method to pass an int array to Delphi. Something like:
    Code:
    export int* send_ds(){
    Or:
    Code:
    export send_ds(int array[]){

  9. #9
    Massively Single Player AverageSoftware's Avatar
    Join Date
    May 2007
    Location
    Buffalo, NY
    Posts
    141
    Not related to your problem, but export is a reserved keyword (rarely implemented, though) in C++. You may want to use a different name for your macro.

  10. #10
    Registered User Adventus's Avatar
    Join Date
    May 2007
    Location
    Canberra, Australia
    Posts
    4
    Quote Originally Posted by AverageSoftware View Post
    Not related to your problem, but export is a reserved keyword (rarely implemented, though) in C++. You may want to use a different name for your macro.
    Good point. Just realised it myself. Although the version of Dev-C++ im using doesnt seem to highlight export....

    Perhaps you can find a method to pass an int array to Delphi. Something like:
    I dont actually have access to the underlying architecture (cant access pointers, except char* ofcourse).... which is a real pain, but there's nothing i can do about it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. dll communicating between each other
    By cloudy in forum C++ Programming
    Replies: 5
    Last Post: 06-17-2005, 02:20 AM
  2. DLL and std::string woes!
    By Magos in forum C++ Programming
    Replies: 7
    Last Post: 09-08-2004, 12:34 PM
  3. .lib vs .h vs .dll
    By Shadow12345 in forum C++ Programming
    Replies: 13
    Last Post: 01-01-2003, 05:29 AM
  4. Passing parameters from VB to C++ through ActiveX DLL
    By torbjorn in forum Windows Programming
    Replies: 0
    Last Post: 12-10-2002, 03:13 AM
  5. Exporting Object Hierarchies from a DLL
    By andy668 in forum C++ Programming
    Replies: 0
    Last Post: 10-20-2001, 01:26 PM