在C#中加载C ++ DLL

时间:2013-03-29 17:00:43

标签: c# c++

我正在尝试使用在C ++中编写但我的应用程序在C#中的DLL

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函数GetProcAddrress()来获取DLL中函数的指针,并使用函数指针完成工作;

  3. 当您不使用DLL或程序结束时,调用Windows的API函数FreeLibrary()来释放库。

  4. 以下是他们提供的示例。

    步骤2.编程用于调用markezd.dll的软件。 a)第一步:动态加载MarkEzd.dll

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

    b)第二步:获取要调用的函数的指针

    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)第三步:调用函数

    1)初始化lmc1板:lmc1_Initial()
      2)打开test.ezd:lmc1_LoadEzdFile(_T(“test.ezd”))
      3)调用lmc1_Mark()进行加工:lmc1_Mark()
      4)关闭lmc1板:lmc1_Close()

    d)第四步,发布markezd.dll:FreeLibrary(hEzdDLL)

    Bellow是命令的描述。

    lmc1_Initial
    意图:初始化lmc1控制板
    定义: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. 选择如下图所示的选项,然后单击“确定”。
    5. 打开项目,选择菜单Project-> Settings。选择“C / C ++”,在“预处理器定义”中添加“UNICODE”并删除“MCBS”
    6. 选择“链接”,在类别中选择“输出”,并在“入口点符号”中添加“wWinMainCRTStartup”
    7. 在源代码中将所有“char”更改为“TCHAR”。
    8. 将双引号“...”包含的所有字符串更改为_T(“...”)
    9. 再次编译并链接项目。
    10. 大多数函数返回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);
              }
          }
      }
      

2 个答案:

答案 0 :(得分:3)

正确的语法如下。

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);
    }
}

答案 1 :(得分:2)

使用P-Invoke调用本机DLL。您可能需要编组某些数据类型才能使其正常工作。

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