我查看了googleverse和堆棧溢出,並且看到了幾個類似的問題,但沒有找到我找到的答案。我是一名新成員,因此我不允許在別人的問題中對答案發表評論以要求澄清,所以我不得不求助於自己的問題。將字符串數組從C#傳遞到C++ dll,然後再返回
好吧,所以我想從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();
}
理論上這應該基於我的研究工作,因爲我已經看到其他幾個人幾乎使用e相同的代碼。在實踐中,發生的事情是我通過:
SetGrammar(new string[] { "b", "a" });
什麼回來了對方:
stringArray[0] =
stringArray[1] = H-▬l☺
在某些情況下不能查看它出於某種原因或其他字符串數組[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] = 8
stringArray[1] =
的C#代碼保持不變。還有什麼我需要改變,我失蹤了?
EDIT2: 剛剛意識到wchar_t的就像是一個字符,而不是一個字符串,不知道爲什麼,我覺得它的表現就像一個字符串。回到繪圖板,需要弄清楚如何最好地複製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;
}
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;
}
,您是否試圖傳遞數組作爲'ref'參數? – 2013-05-08 18:19:25
看到這一點:http://stackoverflow.com/questions/2372061/c-sharp-struct-no-parameterless-constructor-see-what-i-need-to-accomplish和http://stackoverflow.com/questions/ 2345945 /試圖讀取或寫入保護存儲器,這是經常是一個指示,即o和http://stackoverflow.com/questions/2344929/pointers-in-c-sharp-到檢索參考 - 從 - dllimport的功能 – 2013-05-08 18:21:39
和http://stackoverflow.com/questions/2343272/dllimport-unmanaged-non-net-dll-to-net-project-representing-char-and-void – 2013-05-08 18:22:05