Results 1 to 5 of 5

Thread: Consuming a C# dll with dllexports using QLibrary

  1. #1
    Join Date
    Aug 2016
    Posts
    4
    Qt products
    Qt5
    Platforms
    Windows

    Default 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

    Qt Code:
    1. [DllExport("Test", CallingConvention = CallingConvention.StdCall)]
    2. public static string Test()
    3. {
    4. string sMessage = "The quick brown fox jumps over the lazy dog.";
    5.  
    6. return (sMessage);
    7. }
    8.  
    9. [DllExport("SayHello", CallingConvention = CallingConvention.StdCall)]
    10. public static string SayHello([MarshalAs(UnmanagedType.LPWStr)] string pMessage)
    11. {
    12. return (pMessage);
    13. }
    To copy to clipboard, switch view to plain text mode 

    My QT code is

    Qt Code:
    1. int Testptr=0;
    2. int SayHelloptr=0;
    3.  
    4. typedef int (__stdcall *MyPrototype0)();
    5. MyPrototype0 myFunction0 =
    6. (MyPrototype0) QLibrary::resolve("NFX.Trading.Panel.Bridge.dll", "Test");
    7. if (myFunction0)
    8. Testptr = myFunction0();
    9. std::string TestStr = globalclass.mql4_ansi2unicode(Testptr);
    10.  
    11.  
    12.  
    13. static std::string sHello = "Hi There";
    14. typedef long int (__stdcall *MyPrototype1)(std::string pMessage);
    15. MyPrototype1 myFunction1 =
    16. (MyPrototype1) QLibrary::resolve("NFX.Trading.Panel.Bridge.dll", "SayHello");
    17. if (myFunction1)
    18. SayHelloptr = myFunction1((std::string)sHello);
    19. std::string SayHelloStr = globalclass.mql4_ansi2unicode(SayHelloptr);
    To copy to clipboard, switch view to plain text mode 

    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)
    Last edited by ebelcher; 3rd August 2016 at 09:35.

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default 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,
    _

  3. #3
    Join Date
    Aug 2016
    Posts
    4
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Consuming a C# dll with dllexports using QLibrary

    Quote Originally Posted by anda_skoa View Post
    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 View Post
    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.

    Qt Code:
    1. char text[]="Hi There";
    2. wchar_t wtext[20];
    3. mbstowcs(wtext, text, strlen(text)+1);//Plus null
    4. LPWSTR ptr = wtext;
    5.  
    6. typedef long int (__stdcall *MyPrototype1)(LPWSTR pMessage);
    7. MyPrototype1 myFunction1 =
    8. (MyPrototype1) QLibrary::resolve("NFX.Trading.Panel.Bridge.dll", "SayHello");
    9. if (myFunction1)
    10. SayHelloptr = myFunction1((LPWSTR)wtext);
    11. std::string SayHelloStr = globalclass.mql4_ansi2unicode(SayHelloptr);
    To copy to clipboard, switch view to plain text mode 
    Last edited by ebelcher; 4th August 2016 at 07:34.

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Consuming a C# dll with dllexports using QLibrary

    Quote Originally Posted by ebelcher View Post
    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,
    _

  5. #5
    Join Date
    Jul 2019
    Posts
    1
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default 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

Similar Threads

  1. consuming thread usage.
    By wagmare in forum Newbie
    Replies: 7
    Last Post: 4th February 2013, 12:22
  2. How time consuming is a d-pointer access?
    By pospiech in forum Qt Programming
    Replies: 3
    Last Post: 8th June 2010, 10:54
  3. Application consuming 60% of CPU usage ..
    By wagmare in forum Qt Programming
    Replies: 3
    Last Post: 20th October 2009, 11:23
  4. Once again: buttons and time consuming tasks
    By pampo in forum Qt Programming
    Replies: 1
    Last Post: 4th May 2009, 19:26
  5. Show progress of a time consuming operation
    By rainman110 in forum Newbie
    Replies: 7
    Last Post: 10th February 2008, 13:07

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.