0

重複の可能性:
C# P\Invoke DLL に C++ へのエントリ ポイントがありませんか?

SOとGoogleでかなり徹底的なサーフィンを行った後、この質問をしています.ほとんどの答えは約80%の方法で私を導きますが、それでも少し混乱するので、親切に道を教えてください.

次のように定義された Visual C++ 関数がいくつかあります。


MyDLL.h

#ifdef FUNCTIONS_EXPORTS
#define FUNCTIONS_API __declspec(dllexport) 
#else
#define FUNCTIONS_API __declspec(dllimport) 
#endif

namespace Functions {
    class MyFunctions {
    public:
        static FUNCTIONS_API int Add(int a, int b);
        static FUNCTIONS_API int Factorial(int a);
    };
}

MyDLL.cpp

namespace Functions {
    int MyFunctions::Add (int a, int b)
    {
        return a+b;
    }
    int MyFunctions::Factorial (int a)
    {
        if(a<0)
            return -1;
        else if(a==0 || a==1)
            return 1;
        else
            return a*MyFunctions::Factorial(a-1);
    }
}

ここで、このビルドによって生成された DLL を C# プログラムにインポートします。

Program.cs

using System;
using System.Collections.Generic;    
using System.Runtime.InteropServices;

namespace DLLTester
{
    class Program
    {
        [DllImport("path\\to\\the\dll\\myDLL.dll")]
        public static extern int Factorial(int a);
        static void Main(string[] args) {
            int num;
            num = int.Parse(Console.ReadLine());
            Console.WriteLine("The factorial is " + Factorial(num));
        }
    }
}

クラスなしで (定義中にキーワードなしで) 関数を記述しようとしましたstaticが、それでも機能せず、エラーが発生します。

このすべてでどこが間違っているのですか?

4

1 に答える 1

1

私が見る最大の問題は、クラス メソッドを p/invoke しようとしているということです。C++ 名マングリングのため、指定したエントリ ポイントがコンパイル済みの DLL に存在しません。dumpbin.exeDLL を実行して、自分で確認できるはずです。

C++ クラスを使用するとき、私は常に、C++ クラスの作成を処理する C++ 側で「マネージャー」メソッドを作成するというパターンに従いました。作成メソッドは (C++ 側で) オブジェクトを作成し、それを配列に格納して、そのインスタンスをさらに呼び出すために使用する整数 Id を返します。 この記事では、これと同様のアプローチの概要を説明し、クラス インスタンスを直接使用する方法についても説明します (この方法は、単一のコンパイラを使用する場合に決定論的であるはずのマングルされた名前をインポートすることに依存しています)。

名前マングリングの記事とDllImport目的のためにそれを防ぐ方法に目を通し、前の段落にリンクされている CodeProject の記事のほとんどを読むことをお勧めします。それはかなりよく書かれており、多くの p/invoke の詳細をカバーしています。

于 2012-11-04T20:24:20.873 に答える