下面的C++類foo.dll如何通過禁用名稱重整
class a{
private:
int _answer;
public:
a(int answer) { _answer = answer; }
__declspec(dllexport) int GetAnswer() { return _answer; }
}
我想從C#中的PInvoke的getAnswer的PInvoke一個實例方法。要做到這一點,我用下面的方法:
[DllImport("foo.dll", CallingConvention = CallingConvention.ThisCall, EntryPoint= "something")]
public static extern int GetAnswer(IntPtr thisA);
我傳遞一個指向一個(我從別的地方得到的,這不重要)一個IntPtr。 CallingConvention = CallingConvention.ThisCall
確保它的處理正確
這個問題最棒的是我知道我是對的,因爲它已經很好用了!使用Depends.exe,我可以看到「GetAnswer」被導出爲?GetAnswer @ a @@ UAEHXZ(或者某個關閉 - 重點在於它已被名稱損壞)。當我將入侵的名字插入EntryPoint的「東西」時,一切都很好!我花了大約一天的時間才發現使用Depends.exe,因此我將在此留下,以幫助任何有類似問題的人。
我真正的問題是:有沒有什麼辦法來禁用C++名稱重整上的getAnswer讓我不需要把錯位的名字作爲我的切入點。在那裏看到這個名字會被打破,因爲我對名字重組的理解是,如果編譯器改變了,它就會改變。對於我想要pInvoke的每個實例方法,使用Depends.exe都是一個痛處。
編輯:忘了添加我試過的東西: 我似乎不能把extern「C」放在函數聲明中,雖然我可以把它放在定義上。這似乎並沒有幫助,雖然
唯一的其他解決方案,我能想到的是C風格的功能封裝了實例方法和採用的一個實例作爲一個(當你想想看,這是顯而易見的)參數。然後,禁用該包裝器上的名稱修改,然後pInvoke。不過,我寧願堅持已有的解決方案。我已經告訴我的同事pInvoke很棒。如果我必須在C++庫中添加特殊函數才能使pInvoke正常工作,那麼我會看起來像一個白癡。
可能重複的[P/Invoke。如何使用C#編組調用非託管方法?](http://stackoverflow.com/questions/9211128/p-invoke-how-to-call-unmanaged-method-with-marshalling-from-c) –
名稱裝飾實際上非常有用,當您忘記更改pinvoke聲明時,當C++代碼發生更改而不是發生討厭的AccessViolation時,您將得到非常好的錯誤。其他尋找名字的簡單方法是'dumpbin/exports foo.dll'和鏈接器的.map文件。你不能捏住這個函數,需要一個C++/CLI包裝器。 –
@HansPassant你是什麼意思,你不能捏?我已經在這麼做了! –