• C# 与 C++ 互操作(C# 调用 C++ 的动态链接库)


    1.新建 C++ 动态链接库项目

    CPlus.cpp:

    #include "stdafx.h"
    
    extern "C" __declspec(dllexport) void HelloWorld(char* name)
    {
        name[0] = 'c';
    }

    stdafx.h:

    #pragma once
    
    #include "targetver.h"
    
    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    extern "C" __declspec(dllexport) void HelloWorld(char* name);

    编译 C++ 项目得到 DLL 

    2.新建 C# 项目

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace CSharp
    {
        class Program
        {
            [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
            static extern IntPtr LoadLibrary(string lpFileName);        //加载动态链接库
            [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
            static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);     //获取接口地址
            [DllImport("kernel32", EntryPoint = "FreeLibrary", SetLastError = true, CharSet = CharSet.Ansi)]
            static extern bool FreeLibrary(IntPtr hModule);
            private delegate void DelegateHelloWorld(IntPtr a);
    
            private static void Main(string[] args)
            {
                IntPtr hModule = LoadLibrary(@"D:MyProjectCSharpCSharpinDebugCplus.dll");
                IntPtr proc = GetProcAddress(hModule, "HelloWorld");
    
                Byte[] array = new Byte[100];
                array[0] = (byte)'a';
                array[1] = (byte)'b';
                array[2] = (byte)'c';
                IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(array, 0);
                DelegateHelloWorld delegate1 = Marshal.GetDelegateForFunctionPointer(proc, typeof(DelegateHelloWorld)) as DelegateHelloWorld;
    
                delegate1(ptr);
                string str = Encoding.ASCII.GetString(array).Replace("", "");
                Console.WriteLine(str);
    
    
                Console.ReadLine();
            }
        }
    }

    总体效果是 C# 传入 abc 字符串,C++ 的方法将第一个字节改为 c,C# 得到 cbc。

    不同语言之间互相调用需要注意各种数据类型的长度问题,还有编译时选择 32 位 , 64 位的问题。所以使用 数组进行数据交换是比较好的做法。

    在将数组转换为字符串时要注意编码格式,常见的是 ASCII, ANSI, UTF8等。

  • 相关阅读:
    C结构体之位域(位段)
    Linux 有效用户组(effective group)与初始用户组(initial group)(参考鸟哥私房菜)
    牛顿迭代法求平方根
    操作系统 第5章 哲学家问题
    面试题3:数组中重复的数字
    某讯实习生后台开发一面总结
    面试题目4:二维数组中的查找
    Java基础知识之基本概念
    Maven常用命令
    Maven仓库
  • 原文地址:https://www.cnblogs.com/aitong/p/11946427.html
Copyright © 2020-2023  润新知