1

アンマネージC++で記述された32ビットおよび64ビットDLLからC#プロジェクトにいくつかの関数をインポートしようとしています。サンプルとして、私はこれを行いました:

C++DLL関数

long mult(int a, int b) {
    return ((long) a)*((long) b);
}

C#コード

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

namespace ConsoleApplication2
{
    class DynamicDLLImport
    {
        private IntPtr ptrToDll;
        private IntPtr ptrToFunctionToCall;

        [DllImport("kernel32.dll")]
        public static extern IntPtr LoadLibrary(string dllToLoad);

        [DllImport("kernel32.dll")]
        public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);

        [DllImport("kernel32.dll")]
        public static extern bool FreeLibrary(IntPtr hModule);

        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        private delegate int Multiply(int a, int b);
        private Multiply multiply;

        public DynamicDLLImport(string dllName)
        {
            ptrToDll = LoadLibrary(dllName);
            // TODO: Error handling.

            ptrToFunctionToCall = GetProcAddress(ptrToDll, "mult");
            // TODO: Error handling.

            // HERE ARGUMENTNULLEXCEPTION
            multiply = (Multiply)Marshal.GetDelegateForFunctionPointer(ptrToFunctionToCall, typeof(Multiply));
        }

        public int mult_func(int a, int b)
        {
            return multiply(a, b);
        }

        ~DynamicDLLImport()
        {
            FreeLibrary(ptrToDll);
        }
    }

    class DLLWrapper
    {
        private const string Sixtyfour = "c:\\Users\\Hattenn\\Documents\\Visual Studio 2010\\Projects\\ConsoleApplication2\\ConsoleApplication2\\easyDLL0_64.dll";
        private const string Thirtytwo = "c:\\Users\\Hattenn\\Documents\\Visual Studio 2010\\Projects\\ConsoleApplication2\\ConsoleApplication2\\easyDLL0.dll";
//        [DllImport(Sixtyfour)]
//        public static extern int mult(int a, int b);
        [DllImport(Thirtytwo)]
        public static extern int mult(int a, int b);
    }

    class Program
    {
        static void Main(string[] args)
        {
            int a = 5;
            int b = 4;
            DynamicDLLImport dllimp = new DynamicDLLImport("easyDLL0.dll");

            Console.WriteLine(DLLWrapper.mult(a, b));
            //Console.WriteLine(dllimp.mult_func(a, b));

            Console.ReadKey();
        }
    }
}

私はそれを機能させることができないようです。表示されるエラーメッセージは次のとおりです。

  1. 32ビットDLLファイルでDLLWrapperクラスを使用すると、「DLLNotFoundException」が発生しますが、DLLファイルは正確にそのパスにあります。
  2. 64ビットDLLファイルでDLLWrapperクラスを使用し、「PlatformTarget」プロパティを「x64」に変更すると、同じ「DLLNotFoundException」が発生します。「x86」でビルドしようとすると、「BadImageException」が発生します。
  3. DynamicDLLImportクラスを使用すると、コード内で「HEREARGUMENTNULLEXCEPTION」とコメントされた行で常に「ArgumentNullException」が発生します。

私は何が間違っているのですか?

4

4 に答える 4

1

関数を DLL からどのようにエクスポートしましたか? Windows DLL はすべての関数を自動的にエクスポートするわけではなく、C++ は、たとえば、そうしないように指示しない限り、関数のオーバーロードを区別するなどの名前を装飾しますが、正確にはコンパイラ固有であり、他の言語は間違いなくそれを理解していません。

Visual Studio のコマンド プロンプトを起動し、次のコマンドを使用して確認できます。

dumpbin /EXPORTS "your library.dll"
于 2012-07-17T10:28:48.273 に答える
0

Windowsは、コンパイル時だけでなく、実行時にDLLを見つけることができる必要があります。DLLをバイナリフォルダまたはのどこかに置くPATHと、静的インポートが機能します。

于 2012-07-17T08:33:04.543 に答える
0

あなたの C# メソッド宣言は C++ のものと一致しません:

long mult(int a, int b) 

private delegate int Multiply(int a, int b);

戻り値の型を long に変更してみてください。

于 2012-07-17T10:11:52.067 に答える