简体   繁体   中英

Return from C# lib a structure containing a string to c++ program

I am trying to call a C# lib from a C++ program. C# and this interop is pretty new for me. Some of the communications have been easy until I had to face strings inside structures. I have been reading a lot and saw several examples, but I am unable to replicate them and make them work.

I extracted the code with the example of sending a string, and retriving the string which works (_string_exchange). And the method _return_struct which returns a struct with a string that doesnt works. Debugger fails when I try to use the variable for std::cout, with an unhandled exception from 0x00007FFFEA98A388 (KernelBase.dll). The Console.WriteLine havent wrote anything during the call.

I assume this is a problem matching the scrutures. Both are compiled in release x64, using .NET Framework 4.6.1. Also I have been checking with sizeof() and Marshal.SizeOf() to check that both have the same byte length. Also tried to change c++ project character from unicode to multibyte without success.

I saw examples like this that were pretty good explaning everything, but I dont know what I am missing: Passing strings/arrays within structures between C++/C#

C++ program:

struct myStruct
{
    int myInt;
    double myDouble;
    bool myBool;
    char myString[64];
}; 

int main() {
    const TCHAR* pemodule = _T("F:\\PATH\\TO\\DLLsi\\LibCSharp.dll");
    HMODULE lib = LoadLibrary(pemodule);

    typedef LPCSTR(_cdecl *_string_exchange)(LPCSTR s);
    auto pString_exchange = (_string_exchange)GetProcAddress(lib, "_string_exchange");
    LPCSTR test = pString_exchange("LPCSTR test works fine");
    std::cout << test << std::endl;

    typedef myStruct(_cdecl *_return_struct)();
    auto pReturn_struct = (_return_struct)GetProcAddress(lib, "_return_struct");
    myStruct aStruct = pReturn_struct();
    std::cout << aStruct.myString << aStruct.myBool << " " << aStruct.myDouble << " " << aStruct.myInt << std::endl;

    return 0;
}

C# library:

namespace LibCSharp
{    
    public class Class1
    {
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct myStruct
        {
            public int myInt;
            public double myDouble;
            [MarshalAs(UnmanagedType.U1)]
            public byte myBool;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
            public string myString;
        }

        [DllExport]
        public static myStruct _return_struct()
        {
            Console.WriteLine("test");
            myStruct a;
            a.myInt = 3;
            a.myDouble = 2;
            a.myBool = 1;
            Console.WriteLine(a.myBool);
            a.myString = "Hello world! My values are: ";//28
            Console.WriteLine(a.myString);
            return a;
        }

        [DllExport]
        public static string _string_exchange(string s)
        {
            Console.WriteLine(s);
            return s;
        }
    }
}

I am also aiming in a future to make this structure an array, I hope once this is solved I wont face much problems, but any comment in advance is also wellcome.

Thank you in advance

Maybe you should try using Named Pipes to communicate between two processes. It allows you to open stream and transfer any byte arrays. So you can serialize any object to array and transfer it.

Here's working solution for C++ and C# communication.

Pipes are more flexible and system-independent than interop. But probably less efficient...

At first glance, it appears your c# code is marshaling that return string as a tchar[64] which is almost certainly a unicode wchar[64] ; while your C++ code is expecting an ascii char[64] to be there.

Try changing the c++ definition to

struct myStruct
{
    int myInt;
    double myDouble;
    bool myBool;
    TCHAR myString[64];
}; 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM