Consuming a C# dll with dllexports using QLibrary
I have an issue using function from a DLL written in C#. The functions are exported using DLLExport using stdcall. Functions without variables work fine. However, a function with a variable corrupts memory and I can't figure out why.
The DLL code is
Code:
[DllExport("Test", CallingConvention = CallingConvention.StdCall)]
public static string Test()
{
string sMessage = "The quick brown fox jumps over the lazy dog.";
return (sMessage);
}
[DllExport("SayHello", CallingConvention = CallingConvention.StdCall)]
public static string SayHello([MarshalAs(UnmanagedType.LPWStr)] string pMessage)
{
return (pMessage);
}
My QT code is
Code:
int Testptr=0;
int SayHelloptr=0;
typedef int (__stdcall *MyPrototype0)();
MyPrototype0 myFunction0 =
(MyPrototype0
) QLibrary::resolve("NFX.Trading.Panel.Bridge.dll",
"Test");
if (myFunction0)
Testptr = myFunction0();
std::string TestStr = globalclass.mql4_ansi2unicode(Testptr);
static std::string sHello = "Hi There";
typedef long int (__stdcall *MyPrototype1)(std::string pMessage);
MyPrototype1 myFunction1 =
(MyPrototype1
) QLibrary::resolve("NFX.Trading.Panel.Bridge.dll",
"SayHello");
if (myFunction1)
SayHelloptr = myFunction1((std::string)sHello);
std::string SayHelloStr = globalclass.mql4_ansi2unicode(SayHelloptr);
When I call Test(), it returns "The quick brown fox jumps over the lazy dog."
However, when I call SayHello(sHello), the returned string which should be "Hi There" is garbled.
Please note the globalclass.mql4_ansi2unicode simply converts the return string pointer into a local string and I know this function works due to the fact that Test() works and the correct string is returned.
Can anyone point me to my problem?
Thanks
Based on Qt 5.7.0 (MSVC 2013, 32 bit)
Re: Consuming a C# dll with dllexports using QLibrary
Your function signature in the second case looks wrong as far as I guess from the two different languages.
Your DLL annotation looks like it says that the C type of the argument should be LPWStr, but your C++ functon signature uses std::string.
But in your first case you also have "int" as the return type while the C# function has string.
The variable names make even less sense to me, usually "ptr" indicates a pointer, but an int wouldn't be capable of holding a pointer.
Maybe Microsoft's developer documentation has some examples on how to call a C# DLL function from C?
Cheers,
_
Re: Consuming a C# dll with dllexports using QLibrary
Quote:
Originally Posted by
anda_skoa
Your function signature in the second case looks wrong as far as I guess from the two different languages.
Your DLL annotation looks like it says that the C type of the argument should be LPWStr, but your C++ functon signature uses std::string.
But in your first case you also have "int" as the return type while the C# function has string.
The variable names make even less sense to me, usually "ptr" indicates a pointer, but an int wouldn't be capable of holding a pointer.
Maybe Microsoft's developer documentation has some examples on how to call a C# DLL function from C?
Cheers,
_
Thanks for your reply.
As far as I can tell, both the DLL and my code are both using std:string for variables. There are recast as [MarshalAs(UnmanagedType.LPWStr)], I assume for compatibility purposes.
The int for the pointer is fine. It simply hold the address of a pointer to a character array which is accessed using my built in function globalclass.mql4_ansi2unicode. This is working fine.
Somehow, it's my variables that I'm passing that are getting messed up and I don't know why.
Thanks
Quote:
Originally Posted by
anda_skoa
Your function signature in the second case looks wrong as far as I guess from the two different languages.
Your DLL annotation looks like it says that the C type of the argument should be LPWStr, but your C++ functon signature uses std::string.
But in your first case you also have "int" as the return type while the C# function has string.
The variable names make even less sense to me, usually "ptr" indicates a pointer, but an int wouldn't be capable of holding a pointer.
Maybe Microsoft's developer documentation has some examples on how to call a C# DLL function from C?
Cheers,
_
Thanks for your reply.
As far as I can tell, both the DLL and my code are both using std:string for variables. There are recast as [MarshalAs(UnmanagedType.LPWStr)], I assume for compatibility purposes.
The int for the pointer is fine. It simply hold the address of a pointer to a character array which is accessed using my built in function globalclass.mql4_ansi2unicode. This is working fine.
Somehow, it's my variables that I'm passing that are getting messed up and I don't know why.
Thanks
Added after 41 minutes:
Problem solved! After a good nights sleep, I see that the string variables in QT are not LPWSTR as they are in C# and QML. Once I convert the strings into LPWSTR, my DLL functions work like a charm. Now this is solved, I can go back to using QString everywhere.
Below is a very ugly implementation, but it demonstrates the point.
Code:
char text[]="Hi There";
wchar_t wtext[20];
mbstowcs(wtext, text, strlen(text)+1);//Plus null
LPWSTR ptr = wtext;
typedef long int (__stdcall *MyPrototype1)(LPWSTR pMessage);
MyPrototype1 myFunction1 =
(MyPrototype1
) QLibrary::resolve("NFX.Trading.Panel.Bridge.dll",
"SayHello");
if (myFunction1)
SayHelloptr = myFunction1((LPWSTR)wtext);
std::string SayHelloStr = globalclass.mql4_ansi2unicode(SayHelloptr);
Re: Consuming a C# dll with dllexports using QLibrary
Quote:
Originally Posted by
ebelcher
T
The int for the pointer is fine.
This is an asumption that can break easily.
The int might not be as long as a pointer.
E.g. most compilers use 32 bits for int, but a program built for 64 bit has 64 bit sized pointers.
If a pointer can't be passed as a pointer, e.g. void*, then the only safe option is to use an integer type that is specifically meant to store a pointer, e.g. in Qt quintptr.
Cheers,
_
Re: Consuming a C# dll with dllexports using QLibrary
Hello,
I am new on the forum.
I am working for quite some time with the Qt, but am now facing a challenge of integrating a C# library into my c++ project.
For start, I have followed the example, shown/solved on this page, but I fail to use the function.
The library is loaded, but the function can not be resolved (returns false).
I have tried stdCall as well as Cdecl type both without success.
There is another pecularity in my setup - i am working in Linux and compiling for Windows.
I have seen there may be more posobilities when also building in windows, but our complete project is being developed that way, so i can not change that.
Thank you in advance for any hint!
Bostjan