[英]Calling C++ code from C# error using references in c++
在名為“ scandll.dll”的C ++ dll中,我具有以下功能
extern "C" __declspec(dllexport) void scanfile(char * returnstring)
{
strcpy(returnstring, "return string");
}
在我的C#代碼中,我正在這樣做
[DllImport("scandll.dll", CharSet = CharSet.Ansi, SetLastError = true )]
public static extern int scanfile(ref IntPtr strReturn);
這是我用來從dll獲取值的方法
public void Scan()
{
string filename = "";
IntPtr ptr = new IntPtr();
scanfile(ref ptr);//Here i get the error
filename = Marshal.PtrToStringAnsi(ptr);
}
我收到一個異常消息:“試圖讀取或寫入受保護的內存。這通常表明其他內存已損壞。”
我正在追蹤這個連結
在C#中使用C ++引用中的引用從C#錯誤中調用C ++代碼
任何幫助,將不勝感激。
謝謝
您的C ++代碼是錯誤的-它所做的就是更改已傳遞給它的指針的值以指向常量字符串。 呼叫者對該更改一無所知。
就像您執行此操作一樣:
void MyCfunction(int number)
{
number = 3;
}
然后希望該函數的調用者可以在任何地方看到數字“ 3”。
您可以在C ++中執行以下操作:
void MyCFunction(char* pReturnString)
{
strcpy(pReturnString, "Hello, world");
}
但您還需要確保在C#端已提供了帶有指向pReturnString的緩沖區。 一種方法是使用StringBuilder,然后讓C函數的C#聲明采用這樣的參數:
[MarshalAs(UnmanagedType.LPStr)] StringBuilder returnString
在調用C ++函數之前,需要在StringBuilder中保留空間。
在現實生活中,像這樣的C / C ++函數幾乎總是采用一個額外的length參數,該參數允許調用方告知被調用方允許復制到緩沖區的最大字符串長度。 關於長度是否包含終止符\\ 0並沒有約定,因此人們經常小心直到緩沖區的末尾。
memcpy ( destination, * source, size_t num );
嘗試將此值分配給returnstring = "rturn name";
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.