在C#中加载C ++ DLL
我试图使用在C ++中编写但我的应用程序在C#中的DLL
DLL来自另一家公司,但他们为他们的软件提供了SDK。
他们给出了如何在C ++中加载DLL的示例,但我需要将其适应C#。
以下是如何在C ++中执行此操作的说明
MarkEzd.dll文件是动态链接库。
MarkEzdDll.h是MarkEzd.dll中exports函数的头文件
MarkEzd.dll的调用方式是显式链接。 开发人员需要通过调用Windows API函数来加载和释放MarkEzd.dll。
步骤如下。
-
调用Windows的API函数LoadLibrary()动态加载DLL;
-
调用Windows的API函数GetProcAddrress()来获取DLL中函数的指针,并使用函数指针完成工作;
-
当您不使用DLL或程序结束时,调用Windows的API函数FreeLibrary()来释放库。
以下是他们提供的示例。
步骤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)
贝娄是命令的描述。
lmc1_Initial
意图:初始化lmc1控制板
定义: int lmc1_Initial(TCHAR* strEzCadPath, BOOL bTestMode, HWND hOwenWnd)
strEzCadPath:ezcad2.exe存在的完整路径
bTestMode是否处于测试模式
hOwenWnd:具有焦点的窗口。 它用于检查用户的停止消息。 描述:您必须先在程序中的其他function之前调用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文件后通过调用此函数开始标记。 在标记完成之前,该function不会返回。
返回值:常见错误代码
他们还解释了如何设置VS6.0
- 安装visual studio时选择“Microsoft Visual C ++ 6.0”,然后单击“更改选项”。
- 选择“VC ++ MFC和模板库”,然后单击“更改选项”。
- 选择“MS Foundation Class Libraries”并单击“更改选项”。
- 选择如下图所示的选项,然后单击“确定”。
- 打开项目,选择菜单Project-> Settings。 选择“C / C ++”,添加“UNICODE”并删除“预处理器定义”中的“MCBS”
- 选择“链接”,在类别中选择“输出”,并在“入口点符号”中添加“wWinMainCRTStartup”
- 在源代码中将所有“char”更改为“TCHAR”。
- 将双引号“…”包含的所有字符串更改为_T(“…”)
- 再次编译并链接项目。
大多数函数返回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); } } }
很抱歉让这个post在没有正确答案的情况下继续这么长时间。
正确的语法如下。
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); } }
使用P-Invoke调用本机DLL。 您可能必须编组某些数据类型才能使其正常工作。