C#P \调用DLL没有进入C ++的入口点?
我有一个C ++ Dll“TheFoo.dll”,方法“Foo()”
我只需调用以下命令即可访问使用此方法的其他C ++代码:
Foo();
我相信该方法确实有:
__declspec( dllexport )
所以,随着我对P / Invoke所做的阅读,我认为我应该能够简单地从我的C#代码中调用相同的方法:
namespace PInvokeExample1 { /// /// Interaction logic for MainWindow.xaml /// 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 ++的更多信息。 尝试使用extern "C" __declspec(dllexport)
代替。 C ++使用奇怪的名称导出,因此使用extern "C"
可以避免这种情况。
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#声明更容易。 这实际上不是一个好主意,这些装饰名称实际上有助于捕捉错误。
如果你没有在你的dll中声明它是外部的“C”,它的名字很可能被“破坏”了。 您可以使用Dependency Walker之类的内容来查看您的dll导出的符号。
- C#FluentValidation用于类的层次结构
- PetaPoco更新了winforms中的修改记录
- 控制’progressBar1’从我在业务类中创建的线程以外的线程访问
- WPF最佳实践:自定义控件是否适用于MVVM设计?
- 从类库中访问App.Config设置通过unit testing项目调用
- 将datetime2数据类型转换为日期时间数据类型会导致超出范围的值
- 如何使用正则表达式在特定字符串/字符后找到字符串
- 如何在C#中使用System.Reflection.MethodBase找到方法的返回类型?
- 在进行visual studio自动化时,是否有更好的方法来处理RPC_E_CALL_REJECTEDexception?