none
C++で作成したDLLがWindows10で使用できない RRS feed

  • 質問

  • Visual Studio 2017でC#のプログラムを作成しています。

    .Net Frameworkは4.7.1です。

    プログラム内でC++/mfcで作成したDLLをDllImportを使って呼び出しています。

    C++のDLLはVisual Studio2013で作成したものです。

    プログラムをWindows7のPCで動作させると、正常に動作するのですが、

    Windows10のPCで動作させると、DllNotFoundException"指定されたプロシージャが見つかりません"が発生します。

    しかし、同じDLLを使用している.Net Framework4.5を使用したプログラムはWindows10でも動作しています。

    何が原因なのでしょうか。

    以上、よろしくお願いします。

    2018年10月31日 7:42

回答

  • 私の環境(Windows 10 64bit、Visual Studio 2017)で、C# (.Net Framework 4.7.1) のプロジェクトを作成し、Visual Studio 2013 で作成した MFC の DLL (MFC は Static Link) を DllImport でロードし、関数を呼び出してみましたが、ご質問のようなエラーは発生せず、普通に呼び出せました。コードはシンプルで下記のようなもの

    // DLL 側 ( C++ , x86)
    int Test(int i)
    {
    	return i;
    }
    // EXE 側 ( C# , Any CPU)
    using System;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    namespace usedll
    {
        public partial class Form1 : Form
        {
            [DllImport("testdll.dll")]
            private extern static int Test(int i);
            public Form1()
            {
                InitializeComponent();
            }
            private void button1_Click(object sender, EventArgs e)
            {
                int i = Test(199);
                MessageBox.Show(i.ToString());
            }
        }
    }


    DLL は EXE と同じフォルダーに配置しました。ご質問者さんの再現する情報がもう少し欲しいところです。

    ・Debug, Release でも再現しますか?出力された EXE をエクスプローラーから直接実行でも再現しますか?
    ・C++ の関数の宣言はどうなっていますか?C# の DllImport の周辺のコードはどうなっていますか?
    ・DllImport の引数に DLL のフルパスを書いても再現しますか?
    ・該当の DLL の他の関数は呼び出せますか?
    ・新規に DLL を呼び出すためのシンプルな C# のプロジェクトを作成しても再現しますか?
    ・新規に上記のようなエクスポートされる関数が 1 つだけのシンプルな DLL を作成してその呼び出しでも再現しますか?

    • 編集済み kenjinoteMVP 2018年10月31日 12:24
    • 回答としてマーク sadashima 2018年11月2日 0:22
    2018年10月31日 12:14

すべての返信

  • 私の環境(Windows 10 64bit、Visual Studio 2017)で、C# (.Net Framework 4.7.1) のプロジェクトを作成し、Visual Studio 2013 で作成した MFC の DLL (MFC は Static Link) を DllImport でロードし、関数を呼び出してみましたが、ご質問のようなエラーは発生せず、普通に呼び出せました。コードはシンプルで下記のようなもの

    // DLL 側 ( C++ , x86)
    int Test(int i)
    {
    	return i;
    }
    // EXE 側 ( C# , Any CPU)
    using System;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    namespace usedll
    {
        public partial class Form1 : Form
        {
            [DllImport("testdll.dll")]
            private extern static int Test(int i);
            public Form1()
            {
                InitializeComponent();
            }
            private void button1_Click(object sender, EventArgs e)
            {
                int i = Test(199);
                MessageBox.Show(i.ToString());
            }
        }
    }


    DLL は EXE と同じフォルダーに配置しました。ご質問者さんの再現する情報がもう少し欲しいところです。

    ・Debug, Release でも再現しますか?出力された EXE をエクスプローラーから直接実行でも再現しますか?
    ・C++ の関数の宣言はどうなっていますか?C# の DllImport の周辺のコードはどうなっていますか?
    ・DllImport の引数に DLL のフルパスを書いても再現しますか?
    ・該当の DLL の他の関数は呼び出せますか?
    ・新規に DLL を呼び出すためのシンプルな C# のプロジェクトを作成しても再現しますか?
    ・新規に上記のようなエクスポートされる関数が 1 つだけのシンプルな DLL を作成してその呼び出しでも再現しますか?

    • 編集済み kenjinoteMVP 2018年10月31日 12:24
    • 回答としてマーク sadashima 2018年11月2日 0:22
    2018年10月31日 12:14
  • 指定されたプロシージャが見つかりませんだとすると、DLL の依存関係ではなく、本当に指定された関数がその DLL にないのでは?という印象です。

    同じ DLL と言われていますが、本当に同じバージョンですか?
    開発環境で使用している DLL と問題の環境に存在する DLL は同じバージョンですか?
    問題の環境に同名の複数のバージョンの DLL が存在していませんか?

    2018年10月31日 12:51
    モデレータ
  • DllImportで、DllNotFoundExceptionなら、「プロシージャ」は「モジュール」の勘違いじゃないですかね?
    2018年10月31日 13:44
  • 原因は分かりませんが、自己解決しました。

    VisualStudio Installerで修復を行った後、正常に動作するようになりました。

    修復では以下のことを行いました。

    • Visual C++ Redistributable 2017(x86)(x64) の再インストール。
    • Visual C++ Redistributable 2013(x86)(x64)の再インストール。
    • .Net 4.7.1 Developer Pack のインストール。

    症状はDebug、Releaseのどちらでも発生していました。

    また、該当DLLのほかの関数も同様のエラーが発生していました。

    以上、よろしくお願いします。

    2018年11月1日 4:17
  • 間違いなく、同じバージョンのDLLでした。

    また、Windows7で動作していたプログラムをそのままWindows10のPCへコピーし、

    起動しても同様のエラーが発生していました。

    また、DLL内に該当の関数が存在していることをDependency Walkerで確認しています。

    2018年11月1日 4:19
  • 間違いなく、「プロシージャ」です。

    2018年11月1日 4:23