我開始爲這個問題而努力。我搜索並尋找幫助,而我嘗試過的一切似乎都不起作用。我顯然做錯了什麼。將包含未知大小的int數組的結構從c#傳遞給c並返回
反正 - 我有一個C#結構定義爲:
public struct TestStruct
[StructLayout(LayoutKind.Sequential)]
{
public int num;
public IntPtr intArrayPtr;
}
,並在我的C#代碼的主體,我有:
public class Testing
{
[DllImport("testing.dll")]
static extern void Dll_TestArray(out IntPtr intArrayPtr);
public GetArray()
{
IntPtr structPtr = IntPtr.Zero;
TestStruct testStruct;
structPtr = Marshal.AllocHGlobal(Marshal.SizeOf(testStruct));
Marshal.StructureToPtr(testStruct, structPtr, false);
Dll_TestArray(structPtr);
testStruct = (TestStruct) Marshal.PtrToStructure(structPtr, typeof(TestStruct));
}
}
所以現在對C++的一部分。具有結構開始:
struct TestStruct
{
public:
int num;
int* intArray;
}
現在的功能:
extern "C" __declspec(dllexport) void Dll_TestArray(TestStruct *&testStruct)
{
int num = 15;
testStruct->num = num;
testStruct->intArray = new int[num];
for (int i = 0; i < num; i++)
testStruct->intArray[i] = i+1;
}
所以 - 我遇到的問題是,當我得到的結構返回到C#,我的結構是不是如何應該。我可以看到num字段已被正確填寫:它顯示了15.但是,它仍然被設置爲零的IntPtr。在C++中完成的數組創建沒有傳遞給c#。
如果我嘗試退後一步,回到dll函數,我可以看到該數組已創建好,仍然保留該信息。
因此,結構中的c#intptr沒有被設置爲在C++中創建的指針(如果有意義的話)。
所以我的問題真的是 - 如何讓這個工作正確?
我希望能夠從dll中獲得一個包含我需要的所有信息的結構。就是說,在這個例子中,元素的數量和指向數組的指針。這樣,我就可以在intptr上做一個Marshal.Copy來獲取數組。
如果還有另一種方法可以做到這一點,我很樂意做到這一點。我已經嘗試了幾種方法,但無濟於事。這包括試圖在c#下述結構(其中包含int數組,而不是IntPtr的):
public struct TestStruct
{
public int num;
// i have tried various methods to marshal this- eg:
// [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_I4]
public int[] intArray;
}
,我也已經嘗試通過引用本身傳遞結構,而不是一個IntPtr。 對這個問題的任何幫助將大量讚賞。我無法更改C++代碼,但可以更改c#代碼。
這是你的真實密碼?什麼是'structPtr。假'和'TestStruct *&testStruct'?另外,如果'intArrayPtr'被定義爲'out',爲什麼在調用'Dll_TestArray'之前先填充結構?請發佈實際的代碼(剪切和粘貼是一個好主意)。 –
這是非常真實的代碼,是的。這不是特別有用,我只是想獲得一些非常基本的工作,所以我可以在更先進的東西上工作。我編輯了一些錯別字。 我之前沒有使用out參數,但是當我讀到某個地方時,我開始這樣做,這將是一件好事。因此,如果我們使用out參數,那就是爲什麼我使用TestStruct *&testStruct 我已經重命名了一些變量,以便它們對您更有意義。 – user2477533
我在c#中沒有經驗,因此對任何愚蠢的錯誤表示歉意。 – user2477533