簡體   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