私は、C# で実行され、古い C++ コードのクラスと関数を (インポートされた DLL の形式で) 使用するプロトタイプ コード アプリケーションに取り組んできました。コード要件は、クラス オブジェクトを (C# から) アンマネージ C++ DLL に渡し、後で C# アプリケーションによって取得できるように格納/変更することです。これが私がこれまでに持っているコードです...
シンプルな C++ DLL クラス:
class CClass : public CObject
{
public:
int intTest1
};
C++ DLL 関数:
CClass *Holder = new CClass;
extern "C"
{
// obj always comes in with a 0 value.
__declspec(dllexport) void SetDLLObj(CClass* obj)
{
Holder = obj;
}
// obj should leave with value of Holder (from SetDLLObj).
__declspec(dllexport) void GetDLLObj(__out CClass* &obj)
{
obj = Holder;
}
}
C# クラスとラッパー:
[StructureLayout(LayoutKind.Sequential)]
public class CSObject
{
public int intTest2;
}
class LibWrapper
{
[DLLImport("CPPDLL.dll")]
public static extern void SetDLLObj([MarshalAs(UnmanagedType.LPStruct)]
CSObject csObj);
public static extern void GetDLLObj([MarshalAs(UnmanagedType.LPStruct)]
ref CSObject csObj);
}
DLL への C# 関数呼び出し:
class TestCall
{
public static void CallDLL()
{
...
CSObject objIn = new CSObject();
objIn.intTest2 = 1234; // Just so it contains something.
LibWrapper.SetDLLObj(objIn);
CSObject objOut = new CSObject();
LibWrapper.GetDLLObj(ref objOut);
MessageBox.Show(objOut.intTest2.ToString()); // This only outputs "0".
...
}
}
DLL 内で使用できるのはジャンク値だけのようです (渡された C# オブジェクトに由来します)。クラスのマーシャリングまたはメモリ/ポインターの問題で何かが足りないと思います。私は何が欠けていますか?
編集: 上記のコードを変更して、Bond が提案した C#/C++ のメソッド/関数定義の変更を反映させました。渡される値 (1234) は、C# コードによって正しく取得されるようになりました。これにより、C++ DLL の別の問題が明らかになりました。1234 値は C++ コードでは使用できません。代わりに、オブジェクトの DLL 内の値は 0 です。定義済みの C++ 関数を使用して、DLL 内からオブジェクトを編集したいと考えています。これ以上の助けをいただければ幸いです。ありがとう!