4

私はDLLによってエクスポートしたC ++でこのコードを持っています:

typedef struct {
unsigned short major;
unsigned short minor;
} Version;

EXPORTED_FUNC Result Init(Version *version, char *file);

extern "C" Result Init(Version *version, char *file)
{
    if (file) {
    if (!GFile.init(string(file))) {
        return INVALID_PARAMETER;
    }
    if (version) {
        version->major = VERSION_MAJOR1;
        version->minor = VERSION_MAJOR2;
    }

      return OK;
}

私はC#からdllを呼び出しています。これは私がそこに書いたものです:

internal struct Version
{
    ushort major { set; get; }
    ushort minor { set; get; }
}

[DllImport("mydll.dll", CallingConvention=CallingConvention.Cdecl)]
    static extern Result Init(ref Version versionInfo, [MarshalAs`(UnmanagedType.LPStr)] string FilePath);

これは Init の呼び出しです。

string filePath = Application.StartupPath + "\\ABC.ini";
Version version = new Version();

 result = _mydllWrapper.Init(ref version, filePath);

上記のすべてのコードについて、c# アプリケーションを実行しているときに、x64 マシンで次の例外が発生することがあります。

Unable to load DLL mydll.dll : invalid access to memory location (Exception from HRESULT.0x800703E6)

コンパイルからセキュリティ フラグを削除せずにこのコードを修正するにはどうすればよいですか? 修正のためのコードサンプルは本当に歓迎です!

ありがとう!

4

1 に答える 1

1

残念ながら、いくつかの情報が不足していますが、ビルド出力が正しくない場合にのみそのエラーが発生しました。.Net exe の出力ディレクトリをときどき削除してからビルドを実行し、問題が発生した後、新しくビルドされたバイナリをネイティブ出力ディレクトリからコピーしてから先に進むことがあるため、「ときどき」発生するだけです。

この問題を解決するには、.NET コードとネイティブ コードの間でターゲット CPU の種類が適切に一致していることを確認する必要があります。x64 マシンでのみ実行している場合は、AnyCPU を使用できますが、ネイティブ コードを呼び出しているため、x64、x86 などのターゲットに CPU を設定することをお勧めします ( C++ 用語では Win32) または ARM。VS2012 で動作するもう 1 つの代替手段は、「32 ビット優先」ターゲットです。これは、x64 デバイスで x86 として実行できるようにするためにありますが、ARM デバイスでも正常に動作します。

とにかく、構成が正しいことを確認したら、出力ディレクトリが適切に設定されていることを確認して、.NET exe と C++ dll の両方を同じ出力ディレクトリにドロップします。出力ディレクトリは、ビルドとアーキテクチャの組み合わせごとに固有であることに注意してください。

于 2013-01-07T06:13:51.013 に答える