简体   繁体   English

从C#lib返回一个包含字符串的结构到C ++程序

[英]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 ++程序调用C#库。 C# and this interop is pretty new for me. C#和这个互操作对我来说是很新的。 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). 我以发送字符串并检索有效的字符串为例提取了代码(_string_exchange)。 And the method _return_struct which returns a struct with a string that doesnt works. 和_return_struct方法,它返回一个带有无效字符串的结构。 Debugger fails when I try to use the variable for std::cout, with an unhandled exception from 0x00007FFFEA98A388 (KernelBase.dll). 当我尝试将变量用于std :: cout时,调试器失败,但未处理的异常来自0x00007FFFEA98A388(KernelBase.dll)。 The Console.WriteLine havent wrote anything during the call. Console.WriteLine尚未在通话中写任何东西。

I assume this is a problem matching the scrutures. 我认为这是与脚本匹配的问题。 Both are compiled in release x64, using .NET Framework 4.6.1. 两者均使用.NET Framework 4.6.1在x64版中进行编译。 Also I have been checking with sizeof() and Marshal.SizeOf() to check that both have the same byte length. 我也一直在检查sizeof()和Marshal.SizeOf()来检查它们是否具有相同的字节长度。 Also tried to change c++ project character from unicode to multibyte without success. 还尝试将c ++项目字符从unicode更改为多字节,但没有成功。

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 ++ / C#之间的结构内传递字符串/数组

C++ program: C ++程序:

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: C#库:

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. 这是C ++和C#通信的有效解决方案

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] ; 乍一看,您的c#代码似乎在编组,将字符串作为tchar[64]返回,这几乎可以肯定是Unicode wchar[64] while your C++ code is expecting an ascii char[64] to be there. 而您的C ++代码则期望使用ascii char[64]

Try changing the c++ definition to 尝试将c ++定义更改为

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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