6

C++ で記述された DLL を使用しようとしていますが、アプリケーションは C# です。

DLL は別の会社のものですが、彼らは自社のソフトウェア用の SDK を提供しています。

彼らは C++ で DLL をロードする方法の例を示していますが、それを C# に適応させる必要があります。

以下は、C ++でそれを行う方法の指示です

MarkEzd.dll ファイルはダイナミック リンク ライブラリです。

MarkEzdDll.h は、MarkEzd.dll のエクスポート関数のヘッダー ファイルです。

MarkEzd.dll の呼び出し方法は、明示的にリンクされています。開発者は、Windows API 関数を呼び出して MarkEzd.dll をロードおよび解放する必要があります。

手順は次のとおりです。

  1. Windows の API 関数 LoadLibrary() を呼び出して、DLL を動的にロードします。

  2. Windows の API 関数 GetProcAddress() を呼び出して DLL 内の関数のポインターを取得し、関数ポインターを使用して作業を終了します。

  3. DLL を使用しない場合やプログラムが終了した場合は、Windows の API 関数 FreeLibrary() を呼び出してライブラリを解放します。

以下は彼らが提供した例です。

ステップ 2. markezd.dll を呼び出すためのソフトウェアをプログラムします。a) 最初のステップ : MarkEzd.dll の動的ロード

HINSTANCE hEzdDLL = LoadLibrary(_T("MarkEzd.dll"));

b) 2 番目のステップ: 呼び出される関数のポインターを取得する

lmc1_Initial=(LMC1_INITIAL)GetProcAddress(hEzdDLL, _T("lmc1_Initial"));
lmc1_Close=(LMC1_CLOSE)GetProcAddress(hEzdDLL, _T("lmc1_Close"));
lmc1_LoadEzdFile=(LMC1_LOADEZDFILE)GetProcAddress(hEzdDLL,_T("lmc1_LoadEzdFile"));  
lmc1_Mark=(LMC1_MARK)GetProcAddress(hEzdDLL,_T("lmc1_Mark"));

c) 3 番目のステップ: 関数を呼び出す

1) lmc1 ボードの初期化: lmc1_Initial().
2) test.ezd:を開きますlmc1_LoadEzdFile(_T(“test.ezd”))
3) 加工のために lmc1_Mark() を呼び出しますlmc1_Mark()
4) lmc1 ボードを閉じます: lmc1_Close().

d) 4 番目のステップ、markezd.dll のリリース:FreeLibrary(hEzdDLL)

コマンドの説明を以下に示します。

lmc1_Initial
INTENTION: lmc1 コントロール ボードの初期化
DEFINITION: int lmc1_Initial(TCHAR* strEzCadPath, BOOL bTestMode, HWND hOwenWnd)
strEzCadPath: ezcad2.exe が存在するフル パス bTestMode
テスト モードかどうか
hOwenWnd: フォーカスがあるウィンドウ。ユーザーの停止メッセージを確認するために使用されます。説明: プログラム内の他の関数の前に、最初に lmc1¬_Initial を呼び出す必要があります。
戻り値: 一般的なエラー コード

lmc1_Close 意図
: lmc1 ボードを閉じる
定義:int lmc1_Close();
説明: プログラムを終了するときに lmc1_Close を呼び出して lmc1 ボードを閉じる必要があります。
戻り値: 一般的なエラー コード

lmc1_LoadEzdFile 意図
: 指定された ezd ファイルを開き、データベース内のすべてのオブジェクトをクリアします。
定義:int lmc1_LoadEzdFile(TCHAR* strFileName);
説明: この関数は、ユーザーがテンプレートとして作成した ezd ファイルを開くことができます。プロセス パラメータはテンプレート ファイルから読み込まれるため、ユーザーが設定する必要はありません。
戻り値: 一般的なエラー コード

lmc1_Mark 意図
: データベース内のすべてのデータをマークする
定義: int lmc1_Mark(BOOL bFlyMark);
bFlyMark= TRUE // オン フライでマークする
説明: lmc1_LoadEzdFile を使用して ezd ファイルをロードした後、この関数を呼び出してマークを開始します。マーキングが完了するまで、関数は元に戻りません。
戻り値: 一般的なエラー コード

また、VS6.0 のセットアップ方法についても説明します。

  1. Visual Studio のインストール時に「Microsoft Visual C++ 6.0」を選択し、「オプションの変更」をクリックします。
  2. 「VC++ MFC とテンプレート ライブラリ」を選択し、「オプションの変更」をクリックします。
  3. 「MS Foundation Class Libraries」を選択し、「オプションの変更」をクリックします。
  4. 次の図のようにオプションを選択し、[OK] をクリックします。
  5. プロジェクトを開き、メニュー Project->Settings を選択します。「プリプロセッサ定義」で「C/C++」を選択し、「UNICODE」を追加して「MCBS」を削除します</li>
  6. 「リンク」を選択し、カテゴリで「出力」を選択し、「エントリポイント シンボル」に「wWinMainCRTStartup」を追加します</li>
  7. ソース コード内のすべての「char」を「TCHAR」に変更します。
  8. 二重引用符「…」で囲まれたすべての文字列を_T(「…」)に変更
  9. プロジェクトを再度コンパイルしてリンクします。

ほとんどの関数は、成功の整数コード 0 を返します。

これは正しいでしょうか?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;


namespace Start_Mark
{
    public partial class Form1 : Form
    {
        [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);

        [DllImport("MarkEzd.dll")]
        [return: MarshalAs(UnmanagedType.I2)]
        public static extern int lmc1_Initial(string strEzCadPath, bool bTestMode, IntPtr hOwenWnd);

        [DllImport("MarkEzd.dll")]
        [return: MarshalAs(UnmanagedType.I2)]
        public static extern int lmc1_Close();

        [DllImport("MarkEzd.dll")]
        [return: MarshalAs(UnmanagedType.I2)]
        public static extern int lmc1_LoadEzdFile(string strFileName);

        [DllImport("MarkEzd.dll")]
        [return: MarshalAs(UnmanagedType.I2)]
        public static extern int lmc1_Mark(bool bFlyMark);

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            IntPtr hEzdDLL = LoadLibrary("MarkEzd.dll");
            IntPtr iplmc1_Initial = GetProcAddress(hEzdDLL, "lmc1_Initial");
            IntPtr iplmc1_Close = GetProcAddress(hEzdDLL, "lmc1_Close");
            IntPtr iplmc1_LoadEzdFile = GetProcAddress(hEzdDLL, "lmc1_LoadEzdFile");
            IntPtr iplmc1_Mark = GetProcAddress(hEzdDLL, "lmc1_Mark");
            int intlmc1_Initial=lmc1_Initial("c:\temp", false, hEzdDLL);
            if (intlmc1_Initial > 0)
            {
                return;
            }
            int intlmc1_LoadEzdFile = lmc1_LoadEzdFile("c:\temp\test.ezd");
            if (intlmc1_LoadEzdFile > 0)
            {
                return;
            }
            int intlmc1_Mark = lmc1_Mark(true);
            if (intlmc1_Mark > 0)
            {
                return;
            }
            int intlmc1_Close = lmc1_Close();
            if (intlmc1_Close > 0)
            {
                return;
            }
            FreeLibrary(hEzdDLL);
        }
    }
}
4

2 に答える 2

5

正しい構文は次のとおりです。

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

namespace Company.Group
{
    public class FuncList
    {
        [DllImport("MarkEzd.dll", EntryPoint = "lmc1_Initial2", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
        public static extern int Initialize(string PathName, bool TestMode);
    }
}
于 2014-11-07T15:09:29.500 に答える
2

P-Invoke を使用してネイティブ DLL を呼び出します。機能させるために、一部のデータ型をマーシャリングする必要がある場合があります。

http://msdn.microsoft.com/en-us/library/aa288468.aspx

于 2013-03-29T17:07:46.087 に答える