好的,我试图将一个字符串数组从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和一个快乐的面部符号.这显然不是我投入的.
有没有人知道我哪里可能出错?很长一段时间以来我一直在反对这个问题,并且真的可以使用一些帮助,因为感觉我在这里错过了一些非常简单的东西.
编辑:
根据antijon的建议,我确实更改了我的SetGrammarData来制作字符串的副本,但我仍然遇到了问题.
新代码:
(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] = 8stringArray[1] =
C#代码保持不变.还有什么我需要改变的东西,我失踪了吗?
EDIT2:
刚刚意识到wchar_t就像一个char,而不是一个字符串,不知道为什么我认为它表现得像一个字符串.回到绘图板,需要弄清楚如何最好地复制wchar_t **.不是经验丰富的C,但我不认为有可能得到一个wchar_t *的长度,而不是自己传递它,但我将不得不调查它.
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:
以为我让它正常工作,是不正确的.我正在测试一个exe回传给自己但是当通过dll到另一个exe时,没有任何东西会通过.我现在有它工作:
(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时给你的指针不能保证持久化.
总结以上是内存溢出为你收集整理的将一个字符串数组从C#传递给C dll然后再传回全部内容,希望文章能够帮你解决将一个字符串数组从C#传递给C dll然后再传回所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)