2017-04-06 71 views
-1

我有這個CC#代碼工作:C#編組C結構

.H

typedef struct { 

    float a; 
    float b; 

} MyStruct; 

extern MyStruct mystruct; 

__declspec(dllexport) void GetMyStruct (MyStruct* s); 
__declspec(dllexport) void SetMyStruct (MyStruct* s); 

.C

MyStruct mystruct; 

    void GetMyStruct (MyStruct* s) 
    { 

     *s = AeroLink_IOPkt; 
    } 

    void SetMyStruct (MyStruct* s) 
    { 

     AeroLink_IOPkt = *s; 
    } 

void test() 
{ 
    // some code that update element in struct 
    // mystruct.a = 0.4; 
    // mystruct.a = 0.1; 
} 

的.cs

public struct MyStruct 
{ 

    public float a; 
    public float b; 

} 


[DllImport(DLL_NAME, EntryPoint = "GetMyStruct")] 
protected static extern void GetMyStruct(ref MyStruct s); 

[DllImport(DLL_NAME, EntryPoint = "SetMyStruct")] 
protected static extern void SetMyStruct(ref MyStruct s); 

這樣,每次我需要將數據從C#設置爲C時,我必須調用void SetMyStruct,反之亦然,如果我想從C(從無效測試更新)到C#的數據,我必須調用GetMyStruct。我必須每秒做50次。

是否有避免每次撥打SetMyStructGetMyStruct的方法?我希望一次使用SetMyStruct,然後將所有更改反映出來。我不知道這是否可能。

+0

嘗試改變從'struct'到'c​​lass'並刪除各種'ref'關鍵字 – xanatos

+4

從技術上來說,這是一個非常簡單的結構。你可以公開一個返回MyStruct *的函數來返回一個指向c的指針。在你的C#程序中使用'unsafe'代碼來直接訪問它的a和b成員。但是你確實犯了一個錯誤,你沒有檢查你是否需要優化這個代碼。每秒只調用60次,你絕對不會。這是非常快速的代碼,你可以稱它爲每秒數億次。 –

+0

歡迎來到堆棧溢出!如果您還沒有參加,請參加[旅遊],並看看[問],它表示您必須「在發佈任何代碼之前先介紹問題」。 – PJvG

回答

-1

你可以用unsafe和指針來做到這一點。

您需要編譯啓用「不安全」的C#程序。

編輯:一種更好的方式:

添加以下函數庫:

__declspec(dllexport) void GetMyStructRef (MyStruct** s); 
void GetMyStructRef(MyStruct** s) 
{ 
    *s = &mystruct; 
} 

在C#:

[DllImport(DLL_NAME, EntryPoint = "GetMyStructRef")] 
protected static extern void GetMyStructRef(ref MyStruct* s); 

MyStruct* data; 
GetMyStructRef(ref data); 
Console.WriteLine($"{data->a} {data->b}"); 

老答案:

unsafe class MyClass : IDisposable 
{ 
    [DllImport(DLL_NAME, EntryPoint = "GetMyStruct")] 
    protected static extern void GetMyStruct(MyStruct* s); 

    [DllImport(DLL_NAME, EntryPoint = "SetMyStruct")] 
    protected static extern void SetMyStruct(MyStruct* s); 

    GCHandle handle; 
    MyStruct* structRef; 

    public void MyClass() 
    { 
     //we need to get a pinned reference to your struct 
     handle = GCHandle.Alloc(new MyStruct(), GCHandleType.Pinned); 
     structRef = (MyStruct*)handle.AddrOfPinnedObject().ToPointer(); 

     SetMyStruct(structRef); 
    } 

    public void Dispose() 
    { 
     //We need to free the handle to release memory 
     //GC will not collect it without this 
     handle.Free(); 
    } 
} 
+0

如果你打算讓一個非託管資源的課程,你需要使它更復雜一點。 [Lostechies:IDisposable,完成的權利](https://lostechies.com/chrispatterson/2012/11/29/idisposable-done-right/) –