[英]C# P\Invoke DLL no entry point into C++?
我有一個方法為“ Foo()”的C ++ Dll“ TheFoo.dll”
我可以通過簡單地調用以下方法來訪問使用此方法的其他C ++代碼:
Foo();
我相信該方法確實具有:
__declspec( dllexport )
因此,通過閱讀有關P / Invoke的文章,我認為我應該能夠從C#代碼中簡單地調用相同的方法:
namespace PInvokeExample1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
[DllImport(@"C:\MyFolder\TheFoo.dll")]
public static extern
void Foo();
private void button1_Click(object sender, RoutedEventArgs e)
{
Foo();
}
}
}
當我運行它時,出現錯誤:
Unable to find an entry point named 'Foo' in DLL 'C:\MyFolder\TheFoo.dll'.
為什么找不到它的任何想法?
C ++語言支持重載,就像C#一樣。 您可以導出函數void Foo(int)
和函數void Foo(double)
。 顯然,這兩個功能不能都導出為“ Foo”,DLL的客戶端不會知道選擇哪個。 事實並非如此。
C ++編譯器通過修飾函數名稱來解決該問題。 添加額外的字符,使Foo(int)與Foo(double)不同。 您可以通過運行Visual Studio命令提示符中的Dumpbin.exe /exports foo.dll
來查看這些修飾的名稱,該命令列出了導出函數的名稱。 假設您的聲明是相關的,您會看到?Foo@@YAXXZ
。
因此,您的C#程序中的相應聲明應為:
[DllImport("foo.dll", EntryPoint = "?Foo@@YAXXZ",
ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
private static extern void Foo();
有多種方法可以更改C ++函數聲明以使C#聲明更容易。 這實際上不是一個好主意,這些修飾的名稱實際上有助於發現錯誤。
您應該提供有關C ++的更多信息。 嘗試改用extern "C" __declspec(dllexport)
。 C ++導出的名稱很奇怪,因此使用extern "C"
可以避免這種情況。
如果您沒有在dll中將其聲明為extern“ C”,則其名稱可能已被“纏住”。 您可以使用Dependency Walker之類的工具查看dll導出的符號。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.