将一个字符串数组从C#传递给C dll然后再传回
我已经浏览了googleverse和堆栈溢出,并且已经看到了几个类似的问题,但我找到的答案都没有为我工作.我是新会员,所以我不允许在别人的问题上评论答案,要求澄清,所以我不得不求助于我自己.
好的,我试图将一个字符串数组从C#应用程序传递给C dll,然后在另一个C#应用程序中获取该信息.我相信我正确地传递给C但是我无法从dll中获得正确的字符串. 我这样传递给C: [DllImport("KinectPlugins.dll",CallingConvention = CallingConvention.Cdecl)] private static extern void SetGrammarData(string[] strArr,int size); public void SetGrammar(string[] strArr) { SetGrammarData(strArr,strArr.Length); } 我的C代码看起来像这样: #define EXPORT_API __declspec(dllexport) #pragma data_seg(".SHARED") char** grammarData; int grammarDataLength = 0; #pragma data_seg() #pragma comment(linker,"/section:.SHARED,RWS") EXPORT_API void SetGrammarData(char** strArr,int size) { grammarData = strArr; grammarDataLength = size; } EXPORT_API int GetGrammarDataLength() { return grammarDataLength; } EXPORT_API char** GetGrammarData() { return grammarData; } 我在其他C#应用程序中抓取信息的代码如下所示: [DllImport("KinectPlugins.dll")] private static extern IntPtr GetGrammarData(); [DllImport("KinectPlugins.dll")] private static extern int GetGrammarDataLength(); public string[] GetGrammar() { int size = GetGrammarDataLength(); List<string> list = new List<string>(); IntPtr ptr = GetGrammarData(); IntPtr strPtr; for (int i = 0; i < size; i++) { Console.WriteLine("i = " + i); strPtr = Marshal.ReadIntPtr(ptr); list.Add(Marshal.PtrToStringAnsi(strPtr)); ptr += Marshal.SizeOf(typeof(IntPtr)); } return list.ToArray(); } 理论上,这应该基于我的研究,因为我已经看到其他几个人使用几乎相同的代码.实际上,我传入的是: SetGrammar(new string[] { "b","a" }); 另一方面回来的是: stringArray[0] = stringArray[1] = H-?l? 如果某些人由于某种原因无法查看它或另一个stringArray [1]等于H,–,一条粗线,l和一个快乐的面部符号.这显然不是我投入的. 有没有人知道我哪里可能出错?很长一段时间以来我一直在反对这个问题,并且真的可以使用一些帮助,因为感觉我在这里错过了一些非常简单的东西. 编辑: 新代码: (inside the data_seg) wchar_t* grammarData; (end data_seg) EXPORT_API void SetGrammarData(wchar_t* strArr,int size) { delete[] grammarData; grammarData = new wchar_t[size]; std::memcpy(grammarData,strArr,sizeof(wchar_t) * size); grammarDataLength = size; } EXPORT_API wchar_t* GetGrammarData() { return grammarData; } 现在我最终得到了这个输出: stringArray[0] = 8 stringArray[1] = C#代码保持不变.还有什么我需要改变的东西,我失踪了吗? EDIT2: EDIT3: 这是我最终得到的: (inside the data_seg) std::wstring* grammarData; (end data_seg) EXPORT_API void SetGrammarData(wchar_t** strArr,int size) { delete[] grammarData; grammarDataLength = size; grammarData = new std::wstring[size]; for(int i = 0; i < size; i++) { grammarData[i] = std::wstring(strArr[i]); } } EXPORT_API const wchar_t** GetGrammarData() { const wchar_t** wct = new const wchar_t*[grammarDataLength]; for(int i = 0;i<grammarDataLength;i++) { const wchar_t* t = grammarData[i].c_str(); wct[i] = t; } return wct; } Edit4: (inside the data_seg) wchar_t grammarData[32][50] = {}; (end data_seg) EXPORT_API void SetGrammarData(wchar_t** strArr,int size) { grammarDataLength = size; for(int i = 0; i < size; i++) { wcscpy(grammarData[i],strArr[i]); } grammarDataChanged = 1; } EXPORT_API wchar_t** GetGrammarData() { wchar_t** wct = new wchar_t*[grammarDataLength]; for(int i = 0;i<grammarDataLength;i++) { wct[i] = grammarData[i]; } grammarDataChanged = 0; return wct; } 解决方法
这里有几个可能的问题:
>默认情况下,.NET将编组为wchar_t,而不是char.您需要使用MarshalAsAttribute标记输入/输出字符串参数以使用char.>如果要保留字符串,则需要在C函数中复制它们.在函数调用SetGrammarData时给你的指针不能保证持久化. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |