[英]Is it possible to import unmanaged class or struct from DLL using C# DllImport?
正如msdn http://msdn.microsoft.com/en-us/library/aa288468(v=vs.71).aspx所說“平台調用服務(PInvoke)允許托管代碼調用DLL中實現的非托管函數。 “
我想從我用c ++制作的DLL中導入一些類
有可能嗎?怎么樣?
例如,我在DLL中有一些結構:
struct __declspec(dllexport) DLLVector3
{
float x, y, z;
};
struct __declspec(dllexport) DLLQuaternion
{
float x, y, z, w;
};
class __declspec(dllexport) DLLCharacter
{
public:
DLLVector3 position;
DLLQuaternion orientation;
DLLCharacter()
{
}
~DLLCharacter()
{
}
void setPosition(PxVec3 pos)
{
position.x = pos.x;
position.y = pos.y;
position.z = pos.z;
}
void setOrientation(PxQuat or)
{
orientation.x = or.x;
orientation.y = or.y;
orientation.z = or.z;
orientation.w = or.w;
}
};
struct __declspec(dllexport) PhysicalObject
{
DLLCharacter *character;
PxRigidActor *mActor;
PxController *mController;
};
哪種方式可以導入那些? 特別是那些帶指針的結構
您不需要編寫用於訪問的C ++托管代碼 - 但是 - 您無法輕松地在非托管內存和托管內存之間跳轉。 這里有幾個關鍵點1)使用[StructLayout(LayoutKind.Sequential)]來定義映射在c ++結構之上的.net類
[StructLayout(LayoutKind.Sequential)] [Serializable] public struct SFVec3F : IRawStreamIO { public double _x; public double _y; public double _z; }
2)像double,int32等基本類型有效地移動到P / Invoke層 - 更復雜的類型可以獲得thunking的.net變體 - msft doco覆蓋哪些數據類型有效移動,嘗試使用它們
3)C ++版本中指針的所有東西都是.net域中的IntPtr,如果你想要安全,你應該將它視為句柄,即你得到c ++方面對底層結構進行任何操作/訪問
4)訪問本機C ++非常簡單(Handle props是最初源自本機C ++端的IntPtrs)
[DllImport("CS2V3.dll", CharSet = CharSet.Ansi)]
private static extern void AddChild(IntPtr csoPtr, IntPtr childPtr, short recomputeBounds, short adjustCoords, short blindchild);
public void AddChild(V3CSO theChild)
{
AddChild(m_handle, theChild.Handle,0,0,0);
}
5)字符串和其他一些類型需要編組才能獲得.net可用的表單 - 請注意,當您將字符串傳遞給非托管代碼時,這會自動發生,但是當它處於入站代碼時您必須自己執行此操作
[DllImport("CS2V3.dll", CharSet = CharSet.Ansi)]
private static extern IntPtr GetName(IntPtr csoPtr);
[DllImport("CS2V3.dll", CharSet = CharSet.Ansi)]
private static extern void SetName(IntPtr csoPtr, string newName);
public string Name { get { IntPtr np = GetName(m_handle); return Marshal.PtrToStringAnsi(np); } set { SetName(m_handle, value); } }
這是可能的....但您需要在C ++ / CLI中編寫包裝器代碼。 這允許您編寫可以從C#/ .net代碼中使用的類(在外部它是托管代碼),並且在實現中您可以使用C ++代碼。
您無法直接導入C ++類。 只有C風格的功能。 C風格的函數只允許您傳遞C基元類型,這使得它們易於互換。 通常,從非C ++代碼中,幾乎不可能正確傳遞C ++類型。 如果你不能傳入C ++對象,通常很少有你可以調用的有趣函數。
稍后編輯:或者,您可以為非托管功能編寫C風格的包裝函數。 您必須一次性傳遞所有參數(您可以傳遞結構),但您可以使用標准C / C ++編寫包裝器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.