繁体   English   中英

C#P \\ Invoke DLL是否没有C ++的入口点?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM