How to pass string in DLL?
-
Hi All, I wonder who can tell me how to pass a string in DLL? For example, if I make 2 func as: int IntTest() { int loc_int; loc_int = 123; return loc_int; } char *StrTest() { strcpy(glob_buf, "Hello fro DLL"); return glob_buf; } In these 2 funcs, IntTest() works; but StrTest() does not despite it trys to pass a global buffer defined in header file. I used the DLL in my VB application, StrTest() did not work out(no hello-string appeared), but no error popped out. Anybody can help me out? Any kind of hint is appreciated! Huey :confused:
-
Hi All, I wonder who can tell me how to pass a string in DLL? For example, if I make 2 func as: int IntTest() { int loc_int; loc_int = 123; return loc_int; } char *StrTest() { strcpy(glob_buf, "Hello fro DLL"); return glob_buf; } In these 2 funcs, IntTest() works; but StrTest() does not despite it trys to pass a global buffer defined in header file. I used the DLL in my VB application, StrTest() did not work out(no hello-string appeared), but no error popped out. Anybody can help me out? Any kind of hint is appreciated! Huey :confused:
you must say somewhere in you dll that glob_buf is defined (see
extern
keyword). otherwise, why not making this :char* StrTest() {
char* Buff = new char[14];
::strcpy(Buff, "Hell from DLL");
return Buff;
}
TOXCCT >>> GEII power
[toxcct][VisualCalc] -
you must say somewhere in you dll that glob_buf is defined (see
extern
keyword). otherwise, why not making this :char* StrTest() {
char* Buff = new char[14];
::strcpy(Buff, "Hell from DLL");
return Buff;
}
TOXCCT >>> GEII power
[toxcct][VisualCalc]Are you sure this will work ?? ;P You try to write something at a NULL adress ;) Ok, but in fact the problem is not there. The problem is that VB and C++ don't use the same standard from strings. C++ uses zero-terminated strings and VB uses a kind of BSTR string (the length of the string is stored at the begning, each char takes 2 bytes and it is not zero-terminated). You need to use a BSTR string inside your function and return it. I know this is a tricky problem and I spent a lot of time on this to find out a solution. Sorry but I don't remeber exactly of the implementation details but take a look at BSTR strings (specifically this[^] article (and the functions at the end) Hope this helps
-
you must say somewhere in you dll that glob_buf is defined (see
extern
keyword). otherwise, why not making this :char* StrTest() {
char* Buff = new char[14];
::strcpy(Buff, "Hell from DLL");
return Buff;
}
TOXCCT >>> GEII power
[toxcct][VisualCalc]This solution won't work neither ;) You will allocate memory in your dll and then return this string in the program. Two solutions: you don't delete the string -> this will result in a memory leak OR you delete the string and this will result in a runtime error because one basic rule is that the memory allocated by one process must be freed by the same process !! So here you allocate the string in the dll and free it in your program :~
-
Hi All, I wonder who can tell me how to pass a string in DLL? For example, if I make 2 func as: int IntTest() { int loc_int; loc_int = 123; return loc_int; } char *StrTest() { strcpy(glob_buf, "Hello fro DLL"); return glob_buf; } In these 2 funcs, IntTest() works; but StrTest() does not despite it trys to pass a global buffer defined in header file. I used the DLL in my VB application, StrTest() did not work out(no hello-string appeared), but no error popped out. Anybody can help me out? Any kind of hint is appreciated! Huey :confused:
If I understand your problem, you should allocate a string in the main process and pass his pointer to the dll function. In the dll function you can copy the string and then return to main process.
// somewhere in the main process { char* str; str = new char[50]; dll_func(str,50); // use str and clear memory ;) } // somewhere in dll void dll_func(char* str, int max_size) { //use max_size to prevent buffer overflow strcpy(str,"hallo world!"); return; }
-
If I understand your problem, you should allocate a string in the main process and pass his pointer to the dll function. In the dll function you can copy the string and then return to main process.
// somewhere in the main process { char* str; str = new char[50]; dll_func(str,50); // use str and clear memory ;) } // somewhere in dll void dll_func(char* str, int max_size) { //use max_size to prevent buffer overflow strcpy(str,"hallo world!"); return; }
Your idea was right as was your comment but your implementation does not use the max_size parameter. Shouldn't that be : strncpy( str, "hallo world", max_size ); ? Just to be safe I would write the first part something like this :
const int strsize = 50; char* str; str = new char[strsize+1]; dll_func(str,strsize);
This way you will reserve a spot for a null character on the end. -
Your idea was right as was your comment but your implementation does not use the max_size parameter. Shouldn't that be : strncpy( str, "hallo world", max_size ); ? Just to be safe I would write the first part something like this :
const int strsize = 50; char* str; str = new char[strsize+1]; dll_func(str,strsize);
This way you will reserve a spot for a null character on the end.Rick York wrote: Your idea was right as was your comment but your implementation does not use the max_size parameter. 'couse I'm lazy! :) I thought that I solved that problem with my " //use max_size to prevent buffer overflow" ;) Rick York wrote: Shouldn't that be : strncpy( str, "hallo world", max_size ); ? yes.. this should a good implementation. Personally I usually use something like:
int dll_func(char* str,int max_size) { //use max_size to prevent buffer overflow ok.. I'm writing it :) const char dll_str[] = "hallo world!"; //assume that this is a variable caming from somewhere in the dll strncpy(str,"hallo world!",max_size); return strlen(dll_str); }
so in main process you can check (if (dll_func(str,strsize) > strsize)
) if you have truncated the string and the real/needed size. Bye, Francesco :) -
Rick York wrote: Your idea was right as was your comment but your implementation does not use the max_size parameter. 'couse I'm lazy! :) I thought that I solved that problem with my " //use max_size to prevent buffer overflow" ;) Rick York wrote: Shouldn't that be : strncpy( str, "hallo world", max_size ); ? yes.. this should a good implementation. Personally I usually use something like:
int dll_func(char* str,int max_size) { //use max_size to prevent buffer overflow ok.. I'm writing it :) const char dll_str[] = "hallo world!"; //assume that this is a variable caming from somewhere in the dll strncpy(str,"hallo world!",max_size); return strlen(dll_str); }
so in main process you can check (if (dll_func(str,strsize) > strsize)
) if you have truncated the string and the real/needed size. Bye, Francesco :)Nothing of these will work in current context ! The problem is that the function is called from a VB program ! Thus, the first part will work (you can pass a string from VB in a C++ dll by specify it must be passed by val). But this will crash after when you try to read the string in VB. VB and C++ uses different string types...
-
Nothing of these will work in current context ! The problem is that the function is called from a VB program ! Thus, the first part will work (you can pass a string from VB in a C++ dll by specify it must be passed by val). But this will crash after when you try to read the string in VB. VB and C++ uses different string types...
cedric moonen wrote: But this will crash after when you try to read the string in VB. Oh.. I missed that! Well.. I'm not using visual basic but I wrote some dll used by Delphi programs. We solved the same iusse using simple types like arrays of int/char instead of complex types like BSTR or pascal's string. I suppose that you can pass to dll_func a Byte array and then convert it to a string. Something like:
Dim ByteArrayString(50) As Byte
Here you can find something about bytearray to string conversion in Visual Basic. Hope this help. Bye, Francesco