C# 调用C++, C++与C#互相调用
来源:互联网 发布:怎么撩汉子知乎 编辑:程序博客网 时间:2024/05/07 14:02
C# p/invoke: marshaling class between C# and C++ class
1.0 Abstraction
This article provides basic information to realize how pass c# function pointer and class object to a c++ function as parameters.
2.0 Mechanism
The c++ function parameters could be an object pointer or a function pointer. Passing c# class object or a function as parameter to c++ function actually is passing a C# reference or a function pointer. To realize this mechanism properly, first should make sense of the basic knowledge in its scope.
3.0 Basic knowledge
3.1 C# pointer (*)
The c# unsafe code can use pointer directive (*). However, c# pointer has many constraints. As stated in MSDN, “C# pointer types do not inherit from object and no conversions exist between pointer types and object. Also, boxing and unboxing do not support pointers. However, you can convert between different pointer types and between pointer types and integral types.”
“Any of the following types may be a pointer type:
- sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, or bool.
- Any enum type.
- Any pointer type.
- Any user-defined struct type that contains fields of unmanaged types only.”
That means c# cannot make conversion from class object reference to pointer type (*). Using “&” operator on a reference, will cause a compiling error “Cannot take the address of, get the size of, or declare a pointer to a managed type”.
3.2 Reference parameters in C#
While reference object, such as a class object, is pass to function as a parameter, actually the address of object is passed, as reference is a pointer type.
3.3 Class data type in memory
[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
class Class1
{
public int i;
private int _i;
public System.Collections.ArrayList arr = new System.Collections.ArrayList();
public void test()
{
Console.WriteLine("hello world!");
}
public Class1()
{
_i = 400;
}
};
The above graph shows how a Class1 object is allocated memory.
3.4 Delegate in C#
“The delegate keyword is used to declare a reference type that can be used to encapsulate a named or an anonymous method.”(MSDN)
4.0 Marshaling Example
This example passes class object that mentioned in chapter 3.3, to a c++ dll. C++ code use a class type object to accept the fields values of c# object and use a function pointer parameter to accept c# object function.
/////////////////////////////////////////////////////////
//C# Code
///////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace interoperation
{
class Program
{
//////////////////////////////////////////////////////////
//P/Invoke a c++ function declare
///////////////////////////////////////////////////////////
//if do not explcit point out entrypoint
//the c# function name must be the same with c++ code
[System.Runtime.InteropServices.DllImport("..//..//..//debug//sort.dll")]
public static extern void func(Class1 arrays, Program.delgFunc func);
//////////////////////////////////////////////////////////
//C# function pointer declare
///////////////////////////////////////////////////////////
public delegate void delgFunc();
static void Main(string[] args)
{
Class1 obj = new Class1();
Program.delgFunc delg = obj.test;
//pass a class reference and a function pointer to c++ function
func(obj, delg);
}
};
[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
class Class1
{
public void test()
{
Console.WriteLine("c# function is called");
Console.WriteLine("_i="+this._i.ToString());
}
public System.Collections.ArrayList arr = new System.Collections.ArrayList();
private int _i;
public int i;
public Class1()
{
_i = 400;
i = 333;
}
};
}
/////////////////////////////////////////////////////////
//C++ Code
///////////////////////////////////////////////////////////
// Sort.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
extern "C"
{
//////////////////////////////////////////////////////////////////////
//To accept C# class object,
//remember c++ fileds are allocated memory sequentially
///////////////////////////////////////////////////////////////////////
class Class1
{
public :
void * unknow;//accept arr of c# object
int _i;//accept _i of c# object
int i; //accept i of c# object
};
__declspec(dllexport) void func(Class1* class1,void (* test)())
{
cout<<"(C# object is passed !) The value of private field '_i': "<<class1->_i<<"/n";
cout<<"(C# object is passed !) The value of public field 'i': "<<class1->i<<"/n";
test();
}
}
The output like this:
- C# 调用C++, C++与C#互相调用
- C与C++互相调用
- c与c++互相调用
- c++与c互相调用
- c/c++互相调用
- C与C++文件互相调用
- TCL与c/c++的互相调用
- Java与C互相调用实例详解
- Linux汇编与C互相调用
- Java与C互相调用实例详解
- C/C++与Python互相调用
- C/C++与Lua互相调用
- Linux汇编与C互相调用
- TCL与c/c++的互相调用
- python与C/C++互相调用
- lua与c语言互相调用
- lua与C的互相调用
- Linux汇编与C互相调用
- 两个人同时过关
- 陈年:追随PPG 直销衬衫拒绝烧钱
- 继续昨天的工作
- 在C#中调用C/C++代码
- 最棒的Hyper-V监控工具 - Hyper-V Gadget
- C# 调用C++, C++与C#互相调用
- 在JAVA中二进制,八进制,十六进制,十进制间进行相互转换
- 常用JS代码
- Google搜索里的偏好和限制
- [linux] 关于 YUM 的升级安装问题
- 2D游戏引擎(七)——添加MIDI音乐支持
- IE7兼容XMLHttpRequest的问题
- MySql数据库用户密码加密算法研究实现
- 百度宣布任命井上俊一为日本公司总裁