C#調用C++函數入口點的問題 z


C++使用 void extern __declspec(dllexport) 函數名()定義的輸出函數, 在C#中調用時, 如前文所述, 使用
[DllImport("D:\VS2005Projects\Dev_PetroSim2010b\Dev_AMDBR\Debug\Dev_DR_AMDBR.dll", EntryPoint = "#1")]
public static extern void amDBRSurfaceTensionEX(int compCount, int[] components, int modelID, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] double[] Z, ref int errorID);
來調用.

這里注意的是,定義函數入口點的參數EntryPoint = "#1", C#中有2種方式可以定義入口點, 一種是以序號加前綴"#",這是我一直用的,另一種是用EntryPoint="函數名",這種方法我試了很多次卻無法實現,C#編譯器總會說在DLL中 沒有找到函數.

如何找到函數所對應的EntryPoint編號呢?我用的是一個叫DLLExportViewer的軟件,可以告訴你各個函數的Ordinal,即 編號,照此調用即可,但是問題是,如果原DLL進行編輯之后,增加或減少輸出函數之后,各個函數的編號會重新打亂,使原程序無法進行.所以對這種情況,即 DLL尚在編輯之中時,還是以函數名作為EntryPoint比較好.

在C:Program FilesMicrosoft Visual Studio 8VCbin目錄中,有一個文件dumpbin.exe文件和DLLExportViewer一樣可以查看DLL的輸出函數,但是在運行時,居然跳出一個錯誤窗口
查找后發現,mspdb80.dll文件是在C:Program FilesCommon FilesMicrosoft SharedVSA8.0VsaEnv中,將此文件復制到C:Program FilesMicrosoft Visual Studio 8VCbin目錄,再運行時錯誤消失.

查閱dumpbin的輸出,發現輸出函數說明及如下

ordinal hint RVA name
7 6 0002D591 ?amDBRSurfaceTensionEX@@YAXHPAHHPANAAH@Z = @ILT+1420(?amDBRSurfaceTensionEX@@YAXHPAHHPANAAH@Z)
 

前面的ordinal 7即為函數的輸出序號, name列即為可用的函數名,在C#中,改函數聲明為如下即可用函數名作為EntryPoint

[DllImport("D:VS2005ProjectsDev_PetroSim2010bDev_AMDBRDebugDev_DR_AMDBR.dll", EntryPoint = "?amDBRSurfaceTensionEX@@YAXHPAHHPANAAH@Z")]
 

============================================

照上述做法,導出函數可以成功,但是在C#中調用卻是相當麻煩,因為函數的入口名稱太過繁雜且不可理解,因此,還是要解決在C++中的函數輸出,以使在C#中能直接以函數名作為入口.

上述問題中,實際上是在C++中函數輸出時,默認輸出名是使用C++的mangled name, 要使用C的命名方式方可直接使用其輸出名,這時,函數輸出聲明應改為如下:
extern "C" __declspec(dllexport) void amDBREnthalpyEX(int CompCount, int* streamComp, int modelID, double* streamInfo, int& errorID)

這樣,可以看到DLLExportViewer的查看結果了,以此方式聲明的amDBREnthalpyEX函數和以原方式聲明的其他函數的名稱的不同如下圖所示.

這時,在C#中,就可以以函數名稱作為入口點了:
[DllImport("D:VS2005ProjectsDev_PetroSim2010bDev_AMDBRDebugDev_DR_AMDBR.dll", EntryPoint = "amDBREnthalpyEX")]
public static extern void amDBREnthalpyEX(int compCount, int[] components, int modelID, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] double[] Z, ref int errorID);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM