我已经查看了Google和Stack Overflow,并看到了几个类似的问题,但我找到的答案都没有解决我的问题。由于我是一个新成员,所以不允许我在别人的问题中评论以请求澄清,因此我不得不自己提问。
好的,我正在尝试从一个C#应用程序传递一个字符串数组到一个C++ dll,然后在另一个C#应用程序中获取该信息。我相信我已经正确地传递给C++,但无法从dll中获得正确的字符串。
我这样传递给C++:
现在我得到了这个输出:
好的,我正在尝试从一个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、 - 、a粗线、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] = 8
stringArray[1] =
C#代码没有改变。我有遗漏什么需要更改的吗?
编辑2:刚刚意识到wchar_t类似于char,不是字符串,不确定为什么我认为它的行为类似于字符串。回到起点,需要弄清楚如何最好地复制wchar_t**。我对C++不是很熟悉,但我认为不可能在没有自己传递参数的情况下得到wchar_t*的长度,但我将进一步研究。
编辑3:终于让它正常工作了。
这是我的最终结果:
(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;
}
编辑4: 我以为已经正确地做好了,但实际上是错误的。我在测试时使用了一个将exe文件传回本身的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;
}