1. Create a new C ++ DLL projects
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);
Compiling C ++ DLL project was
2. Create a new C # project
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:\MyProject\CSharp\CSharp\bin\Debug\Cplus.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("\0", ""); Console.WriteLine(str); Console.ReadLine(); } } }
The overall effect is C # incoming string abc, C ++ method to the first byte c, C # give cbc.
Each call between different languages to be noted various data types length problem, there is selected 32-bit, 64-bit problem compile time. So use an array of data exchange is a better approach.
When you convert a string array to pay attention to coding format, it is common ASCII, ANSI, UTF8 and so on.