簡體   English   中英

c++/c#編組一個結構來獲得一個固定的指針

[英]c++/c# Marshal a struct to get a fixed pointer

我有一個接受 dll 插件的舊應用程序。 每個插件都有一個 function,它創建一個“小部件”的新實例。 這個 function 通過返回一個唯一的int來標識新的“小部件”實例。 在 c++ 插件模板中,我通過聲明一個新的小部件結構並將其指針轉換為int作為唯一標識符返回來完成(不是我的想法,但我必須使用它):

struct widget {
    ...
};

int widget_instance (HWND hwnd) {
    widget* myWidget = new widget;
    ...
    return (int) myWidget;
}

我正在為這個應用程序開發一個 c# 插件,我需要在 c# 中復制這個機制。 如何在 function 中聲明一個結構,以便每次調用 function 時,它都會返回一個指向新聲明的結構的固定不變指針? 到目前為止我的代碼:

public struct Widget {
   ...
}

public static int widget_instance(uint hwnd) {
    Widget w = new Widget();
    ...
    IntPtr myWidget = Marshal.AllocCoTaskMem(Marshal.SizeOf(w));
    Marshal.StructureToPtr(w, myWidget, false);
    return (int) myWidget;
}

這看起來對嗎? 我是否需要“固定”該結構才能像 c++ 那樣工作?

編輯:詳細說明:唯一 ID 不僅僅是一個簡單的“cookie” int ,實際上稍后在 c++ 模板中使用它來通過將 ID 轉換為指針來訪問結構實例:

widget* w = (widget*) WidgetID;
w->firstElement = 123;

我假設 c# 等效項是:

widget w = (widget)Marshal.PtrToStructure((IntPtr)widgetID,typeof(widget));
w.firstElement = 123;

您似乎暗示返回的 integer 標識符只是一個 cookie,應用程序不會將其視為指針。 這意味着應用程序永遠不會對小部件執行操作,而是始終要求插件代表應用程序執行操作。 如果是這種情況,那么您沒有理由不能使用自己的方案來分配 cookie 標識符。 所以...

您可以將“cookie”成員添加到您的 Widget class 和 static“下一個 cookie”成員以分配 cookies。 這將是一個簡單且語義合理的實現。 顯然它需要線程安全措施。 它還將避免 C++ 將“this”指針轉換為 int 的技術,您說您不喜歡這種技術,盡管我認為它非常好。

除了提供唯一標識符之外,C++ 指針到整數強制轉換技術可能還有第二個目的。 當應用程序為插件提供 cookie 時,插件可以通過將 cookie 轉換回指針來直接以零運行時成本找到小部件。 雖然這幾乎不安全。 但我不認為你可以在 C# 中做到這一點。

您提出的 C# 代碼意味着對於應用程序要求的每個小部件,您都肆意創建和初始化第二個小部件。 如果您真的想模仿 C++ 技術,以保證您的 cookies 在整個進程范圍內是唯一的,而不僅僅是在單個插件中唯一,那么您可以只分配一個字節塊但不初始化它。 甚至是一個零大小的塊,但我不太確定這會產生唯一的地址。

是的,這是正確的,因為AllocCoTaskMem非托管COM 分配器分配 memory。

memory 僅分別通過FreeCoTaskMemReAllocCoTaskMem函數發布或重新定位。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM