2015-01-15 26 views
0

我有3個項目的解決方案。一個C#WinForms項目,它依賴於第二個項目,它是一個C++ DLL。 C++ DLL依賴於第三個項目,它是一個靜態庫。靜態庫是C++類的C代碼。該DLL充當C代碼和C#代碼之間的互操作。通過C#結構在C++中設置變量

我需要通過C#結構設置靜態庫使用的變量。

我沒有在C++/CLI(我已經開始閱讀。在網絡上找到的例子是沒有意義對我來說,截至目前)

到目前爲止,我已經創造了C#結構的經驗。我創建了一個初始化的非託管的內存來容納這個結構:

IntPtr ptData = Marshal.AllocHGlobal(Marshal.SizeOf(objMyClass.data));//data is the structure I am initializing in the constructor of MyClass 
Marshal.StructureToPtr(objPythonInterop.data, ptData, false); 
objCPPClass.UpdateData(ptData);//objCPPClass is object to class in DLL. libClass is the object of class in static library 

這是我的結構在C#:

[StructLayout(LayoutKind.Sequential)] 
public struct Data 
{ 
    members here.. 
} 

在DLL,這是UpdateData功能:

頁眉:

void UpdateData(IntPtr ptrData); 

來源:

void CPPClass::UpdateData(IntPtr ptrData) 
{ 
    m_lib->UpdateDataInLib(ptrData);// m_lib is object to class in static library 
} 

UpdateDataInLib是靜態庫中類中的函數。如何在這個函數中使用ptrData並更新變量?我在靜態庫中有一個類似於我的C#代碼中定義的結構的結構。我如何將ptr投射到這個結構並訪問成員?

我有我的C結構++靜態庫包含了結構的等效成員在C#:

extern "C" __declspec(dllexport) typedef struct Data 
{ 
    members here.. 
}Data, *pData; 

我需要幫助。

+1

我不明白你真的在這裏問什麼......也許你可以提供更多的例子,如C#和C中的結構代碼和互操作調用代碼? –

+1

這樣做沒有任何意義。將C++/CLI源文件中的結構聲明爲「公共值結構」。所以你可以用它作爲你的函數的參數,而不是IntPtr。將它轉換爲本地結構是無聊的一點。 –

+0

@HansPassant:我在我的C++代碼中有一個結構。我想知道的是如何將結構從C#傳遞到靜態庫。如何定義將ptr發送到C#結構的函數,然後將其轉換爲靜態庫中的結構並從中讀取數據。如果我的方法錯了,那麼正確的方法是什麼? – Abhishek

回答

1

有一個更簡單的方法。如果您的DLL在調用後不再訪問該結構,則不需要動態內存分配。只要把結構棧上(你還需要fixed不過):

var data = new objMyClass.data 
{ 
    field1 = value1, // etc 
}; 

unsafe 
{ 
    fixed (objMyClass.data* ptr = &data) 
    { 
     objCPPClass.UpdateData(new IntPtr(ptr)); 
    } 
} 

如果結構是長住,然後讓你的代碼,信息,但不要忘記釋放分配的內存。

然後,在C++的一面,你可以只投:

void CPPClass::UpdateData(IntPtr ptrData) 
{ 
    m_lib->UpdateDataInLib(static_cast<pData>(ptrData.ToPointer())); 
} 

但我不知道UpdateDataInLib簽名,我不知道這種方法。

此外,您可以擺脫IntPtr中間步驟,並只使用一個指針。

+0

謝謝你的回答。我會試試這個。 – Abhishek