20

P / Invokeを学習しようとしているので、C++で簡単なdllを作成しました

KingFucs.h:

namespace KingFuncs
{
    class KingFuncs
    {
    public:
        static __declspec(dllexport) int GiveMeNumber(int i);
    };
}

KingFuns.cpp:

#include "KingFuncs.h"
#include <stdexcept>

using namespace std;

namespace KingFuncs
{
    int KingFuncs::GiveMeNumber(int i)
    {
        return i;
    }
}

したがって、コンパイルされ、このdllをWPFのデバッグフォルダーに次のコードでコピーしました。

[DllImport("KingFuncDll.dll", EntryPoint = "GiveMeNumber", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern int GiveMeNumber(
              int i
              );

そしてボタンクリックでそれを呼び出します:

private void Button_Click(object sender, RoutedEventArgs e)
{
    int num = GiveMeNumber(123);
}

しかし、それは私に例外を与えます:

DLL「KingFuncDll.dll」で「GiveMeNumber」という名前のエントリポイントが見つかりません。

本当に....私が間違ったことをしました...それは明らかにDLLを見つけることができます、さもなければ別の例外でしょう。しかし、私のメソッド名はまったく同じです....他の理由は考えられません。

4

3 に答える 3

39

extern "C"C ++の名前マングリングを抑制するために、関数をエクスポートするときに使用する必要があります。また、クラスのメンバーにp/invokeを試みるべきではありません。代わりに無料の関数を使用してください。

extern "C" {
    __declspec(dllexport) int GiveMeNumber(int i)
    {
        return i;
    }
}

管理側では、DllImport属性がすべて間違っています。SetLastErrorWin32API専用のどちらを使用しないでください。CharSetテキストパラメータがない場合は、設定を気にしないでください。の必要はありませんExactSpelling。そして、呼び出し規約はおそらくCdeclです。

[DllImport("KingFuncDll.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern int GiveMeNumber(int i);
于 2012-04-11T16:02:25.563 に答える
0

問題は、C++クラス内でC++の「関数」を宣言し、P/InvokeにStdCallを使用するように指示していることです。

クラスの外でC++関数を宣言し、それをエクスポートするようにしてください。その後、コードが機能するはずです。

クラス内にC++関数が本当に必要な場合は、CallingConvention.ThisCallを参照してください。ただし、アンマネージクラスインスタンスを作成し、それをP/Invoke呼び出しの最初のパラメーターとして渡す必要があります。

于 2012-04-11T16:06:35.340 に答える
0

dllファイルのエントリポイント名は、他のソースファイルが存在するデバッグフォルダにある.expファイルで指定されます。dumpbinが機能しない場合は、これを試すことができます。

于 2017-04-13T08:39:59.470 に答える