加载C ++ DLL在C# [英] Loading a C++ DLL in C#

查看:2645
本文介绍了加载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函数GetProcAddrress()获取DLL中的函数指针并使用函数指针完成工作;


  3. 当您不使用DLL或程序结束时,调用Windows的API函数FreeLibrary ol>

    下面是他们提供的示例。



    步骤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

    INTENTION:关闭lmc1板

    定义: int lmc1_Close();

    说明:必须调用lmc1_Close在退出程序时关闭lmc1板。

    返回值:常见错误代码



    lmc1_LoadEzdFile

    注意:打开指定ezd文件,并清除数据库中的所有对象。

    DEFINITION: int lmc1_LoadEzdFile(TCHAR * strFileName);

    说明:此函数可以打开由用户作为模板构建的ezd文件。用户不需要设置过程参数,因为它们将从模板文件加载。

    返回值:常见错误代码



    lmc1_Mark

    INTENTION:标记数据库中的所有数据

    DEFINITION: int lmc1_Mark(BOOL bFlyMark);

    bFlyMark = TRUE //即时标记

    DISCRIPTION:使用lmc1_LoadEzdFile加载ezd文件后,通过调用此函数开始标记。该函数在标记完成之前不会返回。

    返回值:常见错误代码



    它们还说明如何设置VS6.0




    1. 在安装visual studio时选择Microsoft Visual C ++ 6.0,然后点击更改选项。

    2. 选择VC ++ MFC和模板库,然后点击更改选项。

    3. 选择MS基础类库,然后单击更改选项。

    4. 选择如下图所示的选项,然后点击确定。

    5. 打开项目,选择菜单Project-> Settings。在预处理器定义中选择C / C ++,添加UNICODE并删除MCBS。

    6. 选择链接,在类别中选择输出,然后添加wWinMainCRTStartup Entry-point symbol

    7. 在源代码中将所有char更改为TCHAR。

    8. 更改双引号引起的所有字符串...to _T(...)

    9. 再次编译并链接项目。



    这是正确的吗?

      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;


    命名空间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);
    }
    }
    }


    解决方案



    正确的语法如下。

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

    命名空间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);
    }
    }


    I am trying to use a DLL that was writen in C++ but my application is in C#

    The DLL is from another company but they have supplied an SDK for their software.

    They give an example of how to load their DLL in C++ but I need to adapt it to C#.

    Below is their instructions of how to do it in C++

    MarkEzd.dll file is Dynamic Link Library.

    MarkEzdDll.h is header file of the exports function in MarkEzd.dll

    The calling way of MarkEzd.dll is explicitly link. Developer needs to load and free MarkEzd.dll by calling Windows API function.

    The steps are as follows.

    1. Call Windows’ API function LoadLibrary() to load DLL dynamically;

    2. Call Windows’ API function GetProcAddrress() to get the pointer of the functions in the DLL and use the function pointer to finish the work;

    3. Call Windows’ API function FreeLibrary() to release library when you do not use DLL or the program ends.

    Below is the example they have provided.

    Step 2. Program software for calling markezd.dll. a) First step : Dynamic Load MarkEzd.dll

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

    b) Second step: get the pointer of the function to be called

    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) Third step: Call the function

    1) Initialization lmc1 board: lmc1_Initial().
    2) Open test.ezd: lmc1_LoadEzdFile(_T("test.ezd")).
    3) Call lmc1_Mark() for machining: lmc1_Mark().
    4) Close lmc1 board: lmc1_Close().

    d) Fourth step, Release markezd.dll: FreeLibrary(hEzdDLL)

    Bellow is the descriptions of the commands.

    lmc1_Initial
    INTENTION: initialize lmc1 control board
    DEFINITION: int lmc1_Initial(TCHAR* strEzCadPath, BOOL bTestMode, HWND hOwenWnd)
    strEzCadPath: the full path where ezcad2.exe exists
    bTestMode Whether in test mode or not
    hOwenWnd: The window that has the focus. It is used to check the user’s stop messages. DESCRIPTION: you must first call lmc1¬_Initial before other function in program.
    RETURN VALUE: common error code

    lmc1_Close
    INTENTION: Close lmc1 board
    DEFINITION: int lmc1_Close();
    DESCRIPTION: you must call lmc1_Close to close the lmc1 board when exit program.
    RETURN VALUE: common error code

    lmc1_LoadEzdFile
    INTENTION: open the appointed ezd file, and clear all the object in database.
    DEFINITION: int lmc1_LoadEzdFile(TCHAR* strFileName);
    DESCRIPTION: this function can open an ezd file that was build by user as a template. User need not set process parameters, because they will be loaded in from the template file.
    RETURN VALUE: common error code

    lmc1_Mark
    INTENTION: mark all the data in database
    DEFINITION: int lmc1_Mark(BOOL bFlyMark);
    bFlyMark= TRUE // mark on fly
    DISCRIPTION: Begin to mark by calling this function after loading ezd file using lmc1_LoadEzdFile. The function will not return back until marking complete.
    RETURN VALUE: common error code

    They also explain how to set up VS6.0

    1. Choose "Microsoft Visual C++ 6.0" when install visual studio, and click "Change Option".
    2. Choose "VC++ MFC and Template Libraries" and click "Change Option".
    3. Choose "MS Foundation Class Libraries" and click "change option".
    4. Choose the options as following picture, and click "OK".
    5. Open the project, choose menu Project->Settings. Choose "C/C++", add "UNICODE" and delete "MCBS" in "Preprocessor definitions"
    6. Choose "Link", select "Output" in Category, and add "wWinMainCRTStartup" in "Entry-point symbol"
    7. Change all "char" to "TCHAR" in source code.
    8. Change all character string included by double quotation marks "…" to _T("…")
    9. Compile and link the project again.

    most of the functions return an integer code of 0 for success.

    Would this be correct?

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

    解决方案

    Sorry for letting this thread to go on without the correct answer for so long.

    The correct syntax is as follows.

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

    这篇关于加载C ++ DLL在C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆