C++ library

library.h

#ifndef __LIBRARY_H__  
#define __LIBRARY_H__

//exports.def
#ifdef __cplusplus    //__cplusplus是cpp中自定义的一个宏
extern "C" {          //告诉编译器,这部分代码按C语言的格式进行编译,而不是C++的
#endif

#define LIB_EXPORTS __declspec(dllexport)

// 回调函数必须指定 __stdcall, 否则C#调用会闪退
typedef void(__stdcall *OnConnected)(int code, int msg);

void connect(char* url, OnConnected onConnected);

// 可以.def文件导出库,也可以使用 __declspec(dllexport) 指定
//LIB_EXPORTS void show_info();
void show_info();

int add(int a, int b);

#ifdef __cplusplus
}
#endif

#endif//__LIBRARY_H__

library.cpp

#include "library.h"
#include <stdio.h>

void show_info() {
    printf("### library => show_info() ###\n");
}

void connect(char* url, OnConnected onConnected){
    printf("### connect to %s ###\n", url);
    onConnected(1, 2);
    printf("### connected success ###\n");
    return;
}

int add(int a, int b) {
    return a + b;
}

exports.def

LIBRARY library
EXPORTS
    show_info=show_info
    add=add
    connect=connect

C# 调用 C++ library

library.cs

using System.Runtime.InteropServices;

namespace echo_csharp
{

    class library
    {
        public delegate void MyOnConnected(int code, int msg);

        //public static OnConnected onConected;

        [DllImport("library.dll", EntryPoint = "connect", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
        public static extern int connect(string url, MyOnConnected f);

        [DllImport("library.dll", EntryPoint = "add", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
        public static extern int add(int a, int b);

        [DllImport("library.dll", EntryPoint = "show_info", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
        public static extern void show_info();
    }
}

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace echo_csharp
{
    class Program
    {
        static void myOnConnected(int code, int msg){
            Console.WriteLine("myOnConnected");
            Console.ReadLine();
        }

        static void Main(string[] args)
        {
            Console.WriteLine("add 1, 2 = "+library.add(1,2));
            library.show_info();
            Console.WriteLine("hello");
            Console.ReadLine();

            library.connect("http://www.cloudtalkers.com", myOnConnected);
            Console.WriteLine("###############");
            Console.ReadLine();
        }
    }
}

C++ 结构体指针传递

c++ 代码

typedef struct _Person
{
  char name[128];
  int age;
}Person

__declspec(dllexport) void GetPerson(Person *p);

对应的C# 代码

[StructLayout(LayoutKind.Sequential)]
public struct Person
{
  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
  string name;
  int age;
}
void GetPerson(ref Person p);

调用 GetPerson

Person p = new Person();
GetPerson(ref p);

struct 返回值问题

不能直接返回struct
https://support.microsoft.com/en-us/kb/2022749
http://stackoverflow.com/questions/27201996/c-sharp-methods-type-signature-is-not-pinvoke-compatible
http://stackoverflow.com/questions/22803083/methods-type-signature-is-not-pinvoke-compatible

C# socks5代理

using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text;...

阅读全文

欢迎留言