[英]C# / C++ Interop: How to modify class in C++ memory from C#
我在我的 C++ 項目中包含一個 C# DLL,我希望兩者都能夠輕松編輯相同的結構或 memory 中的 class 我可以使用函數來設置/獲取成員或結構,但我認為這會有很多更多的開銷和麻煩。 我寧願能夠直接編輯成員變量,將 C# 端的 memory 映射到匹配 C++ 端。
我正在使用 Mono 來管理來自 C++ 的 C#,但我不確定這是否重要。
這是我這樣做的嘗試,但 C# 中的任何更改只會影響 C# 結構。 我怎樣才能解決這個問題?
C++(非托管)代碼:
#ifdef ENGINE_CORE
#define ENGINE_CORE_API __declspec(dllexport)
#else
#define ENGINE_CORE_API __declspec(dllimport)
#endif
struct TestStruct {
int myElement = 4;
};
TestStruct testStruct;
extern "C" {
ENGINE_CORE_API void GetTestStruct(TestStruct** transf) {
*transf = &testStruct;
}
}
C#(托管)代碼:
[StructLayout(LayoutKind.Sequential)]
class TestStruct {
public int myElement;
};
public class Example {
// Called in a loop:
public void OnUpdate() {
GetTestStruct(out TestStruct testStruct);
testStruct.myElement += 2;
Logger.Print($"Int: {testStruct.myElement}");
}
#region DllImports
[DllImport("EngineCore")]
static extern void GetTestStruct([Out] out TestStruct comp);
#endregion
}
Output:
[2022-02-26 00:02:54.959] [Debug Logger] [info] Int: 6
[2022-02-26 00:02:55.220] [Debug Logger] [info] Int: 6
[2022-02-26 00:02:55.234] [Debug Logger] [info] Int: 6
預計 Output:
[2022-02-26 00:02:54.959] [Debug Logger] [info] Int: 6
[2022-02-26 00:02:55.220] [Debug Logger] [info] Int: 8
[2022-02-26 00:02:55.234] [Debug Logger] [info] Int: 10
從 C# 端,您可以將 object 實例的所有字段的所有相對 memory 地址偏移量帶入 C++ 並使用添加到其 object 地址的偏移量訪問它們並轉換為它們的 POD 類型。
那么您的 C++ class 將僅由直接指向 C# object 字段的指針組成。
struct TestStruct {
// points to relevant field
int* myElement;
};
TestStruct t({ptr_from_csharp});
*t.myElement=5; // pinned C# object's field changes
如果您需要相反的東西,那么 C++ 端不需要額外的固定操作,因為它沒有 GC。
如果你不想擺弄指針類型字段,那么你可以在 C# 上重載字段的 getter/setter 並在這些 getter/setter 方法中運行 C++ DLL 這樣它看起來像 C# 從外部擁有 memory 但實際上只改變C++ 空間 memory。
class TestStruct {
public int myElement {
get { return cpp("C++");}
set { cpp("change C++");}
}
};
但這會帶來互操作開銷。
我會編寫某種 awk 或 perl 腳本來讀取 C# class 並吐出所需的 C++ 結構。
為此,這將有助於:
使用腳本識別並用於標識所述類的注釋來注釋或括起 C# 類
將 C++ 結構移動到單獨的 header 文件
然后,當 C# class 更改時,只需在相關文件上運行腳本並重新編譯您的 C++ 代碼。
不要忘記讓腳本寫出注釋 output 文件是機器生成的效果,這樣您就不會無意中手動編輯它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.