C#获得C++写的托管动态库的字符串集合

    技术2022-05-14  15

    问题提出,在C++中写了一个函数比如extern "C" __declspec(dllexport) void fun1(char** cdatas){  cdatas[0] = "0/0";  cdatas[1] = "1/0";  cdatas[2] = "2/0";}在C#中调用  [DllImport("fun1.dll",                  EntryPoint = "fun1",                   CharSet = CharSet.Ansi,                   CallingConvention = CallingConvention.StdCall)]        public static extern bool void fun1([In][Out] string[] path)                 static void Main(string[] args)        {             string[] strs = new string[3];              fun1(strs);        } 此时调用正确,strs中的值是0,1,2;但是如果C++中fun1函数是这样的extern "C" __declspec(dllexport) void fun1(char** cdatas){  const char* c0 = "0/0";  const char* c1 = "1/0";  const char* c2 = "2/0";  cdatas[0] = c0;  cdatas[1] = c1;  cdatas[2] = c2;}C#再调用就会发现strs为空的。这个问题参考了网上诸多大虾的例子,才解决,所以要写下来。C#是宽字符,在C++中宽字符是wchar_t;但是为什么直接写cdatas[0] = "0" ……能成功呢,我想可能是C#中的string调用了重载的"="吧,因为在C#中直接写 string str1 = "test1";是对的。但是这个我不能确定。

    具体修改方法是,将C++的代码改成extern "C" __declspec(dllexport) void fun1(wchar_t** cdatas){  //std::locale old_loc = std::locale::global(std::locale(""));  有中文时需要  const char* c0 = "0/0"; wchar_t wc0[2] = L"/0"; mbstowcs( wc0, c0, 2);

     

      const char* c1 = "1";  wchar_t wc1[2] = L"/0"; mbstowcs( wc1, c1, 2);   const char* c2 = "2";  wchar_t wc2[2] = L"/0"; mbstowcs( wc2, c2, 2);   cdatas[0] = wc0;  cdatas[1] = wc1;  cdatas[2] = wc2;    //std::locale::global(old_loc); 有中文时需要}

     

    这里要注意wchar_t的长度一定要=char的长度加1;否则在C#端出现乱码。在C++工程中选常规->字符集->使用 Unicode 字符集 公共语言运行支持->公共语言运行时支持(/clr).

    在C#代码中修改 CharSet = CharSet.Ansi,为 CharSet = CharSet.Auto就OK了。

     


    最新回复(0)