• 《精通.NET互操作1.2》C# PInvoke使用c++dll


    书本章节:1.2 Hello,World实例程序

    第一步:生成c++的dll,参考文章:https://blog.csdn.net/liyunxin_c_language/article/details/83210788

    注意事项1:如果导出的dll出现函数名是乱码的情况,要在导出函数前增加 extern "C",如下

    extern "C" MYDLL_API  int mySum(int a, int b)
    {
    return a + b;
    }

    注意事项2:

    因为该头文件既被dll的源文件包含,又被使用方包含,所以开头使用条件编译——当被dll源文件包含时(#ifdef MYDLL_EXPORTS,因为vs生成的DLL项目默认都定义了DLL名称_EXPORTS这个宏),导出的函数前要加__declspec(dllexport)宏;如果是被使用方包含,则导出函数前要加__declspec(dllimport)宏

    在vs中的创建步骤

    创建项目。在vs中新建win32应用程序,名称为任意给定,如MyDll之类的,概述点击下一步,应用程序设置中的应用程序类型选择DLL(D),完成。

    添加头文件。在项目-添加新项-**Visaul C++**中选择头文件,设置文件名如MyDll.h。

    头文件代码如下:

    #ifdef MYDLL_EXPORTS
    #define MYDLL_API __declspec(dllexport)//注意decl前面是两个下划线
    #else
    #define MYDLL_API __declspec(dllimport)
    #endif
    
    namespace MyDllSpace
    {
        //导出类
        class MyDllClass
        {
        private:
            double a;
        public:
            //导出的函数
            MYDLL_API MyDllClass();
            MYDLL_API MyDllClass(double a_);
            MYDLL_API double multiply(double b);
            MYDLL_API void display();
            MYDLL_API static void conbine(MyDllClass m1, MyDllClass m2);
        };
    }

    源文件代码如下:

    // MyDll.cpp : 定义 DLL 应用程序的导出函数。
    //
    
    #include "stdafx.h"
    #include "MyDll.h"
    #include <iostream>
    
    MyDllSpace::MyDllClass::MyDllClass()
    {
        a = 0;
    }
    
    MyDllSpace::MyDllClass::MyDllClass(double a_)
    {
        a = a_;
    }
    
    MYDLL_API double MyDllSpace::MyDllClass::multiply(double b)
    {
        return a*b;
    }
    
    MYDLL_API void MyDllSpace::MyDllClass::display()
    {
        std::cout << "a=" << a << std::endl;
    }
    
    MYDLL_API void MyDllSpace::MyDllClass::conbine(MyDllClass m1, MyDllClass m2)
    {
        std::cout << "(" << m1.a << "," << m2.a << ")" << std::endl;
    }
    
    extern "C" MYDLL_API
    int mySum(int a, int b)
    {
        return a + b;
    }

    第二步,用C#调用刚才生成的C++的dll

    将生成的dll拷贝到C#项目中的debug文件夹(和.exe放在同一个目录)

    调用代码如下

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace PInvoke12
    {
        class Program
        {
            static void Main(string[] args)
            {
                Win32APIcOnsoleHelloWorld.SayHelloWorld();
                int a = 1;
                int b = 2;
                int c = Win32APIcOnsoleHelloWorld.mySum(a, b);
                Console.Write(c.ToString());
                Console.WriteLine();
            }
        }
    
        class Win32APIcOnsoleHelloWorld
        {
            [DllImport("msvcrt.dll")]
            static extern int puts(string msg);
    
            [DllImport("msvcrt.dll")]
            static extern int _flushall();
            /// <summary>
            /// 调用自己写的dll
            /// </summary>
            /// <param name="a"></param>
            /// <param name="b"></param>
            /// <returns></returns>
            [DllImport("MyDll.dll")]
            public static extern int  mySum(int a, int b);
            public static void SayHelloWorld()
            {
                puts("Hello,world");
                _flushall();
            }
        }
    }
  • 相关阅读:
    ORACLE 计算时间相减间隔
    oracle中游标详细用法
    oracle中计算某月的天数
    Unity3D导出的EXE不用显示分辨率选择界面
    Unity3D 之暂停和继续的实现
    double的值太大,以及补0
    Unity3D鼠标点击物体产生事件
    java POi excel 写入大批量数据
    Unity3D 判断鼠标是否按在UGUI上
    Unity3D 之UGUI 滚动条
  • 原文地址:https://www.cnblogs.com/xuelixue/p/11872192.html
Copyright © 2020-2023  润新知