Ada*_*dam 6 c# c++ string dll char
我已经浏览了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);
}
Run Code Online (Sandbox Code Playgroud)
我的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;
}
Run Code Online (Sandbox Code Playgroud)
我在其他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();
}
Run Code Online (Sandbox Code Playgroud)
理论上,这应该基于我的研究,因为我已经看到其他几个人使用几乎相同的代码.实际上,我传入的是:
SetGrammar(new string[] { "b", "a" });
Run Code Online (Sandbox Code Playgroud)
另一方面回来的是:
stringArray[0] =
stringArray[1] = H-?l?
Run Code Online (Sandbox Code Playgroud)
如果某些人由于某种原因无法查看它或另一个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;
}
Run Code Online (Sandbox Code Playgroud)
现在我最终得到了这个输出:
stringArray[0] = 8
stringArray[1] =
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
编辑4: 以为我让它正常工作,是不正确的.我正在测试一个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;
}
Run Code Online (Sandbox Code Playgroud)
小智 3
这里有几个可能的问题:
wchar_t,而不是char. 您需要使用MarshalAsAttribute标记输入/输出字符串参数才能使用 char。SetGrammarData不保证在函数调用中提供给您的指针持续存在。