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

本文探讨了在C++与C#之间进行跨平台函数调用时遇到的问题及解决方案,特别是在处理字符串传递时的注意事项。文章详细介绍了如何在C++中正确设置wchar_t类型以便与C#中的string类型兼容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题提出,在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了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值