C# 调用C++, C++与C#互相调用
2008-08-01 12:55
344 查看
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++代码&.net 代码安全)
- C#托管代码与C++非托管代码互相调用
- C#托管代码与C++非托管代码互相调用一(C#调用C++代码&.net 代码安全)
- 打通 C++ 和 C# 关于 COM 组件互相调用的任督二脉
- 老生常谈之C++和C#之间互相调用
- C#托管代码与C++非托管代码互相调用一(C#调用C++代码&.net 代码安全)
- c#编程指南——平台调用P-INVOKE完全掌握,C#和C++互相调用
- 老生常谈之C++和C#之间互相调用
- C#托管代码与C++非托管代码互相调用二(C++调用C#代码)
- C++ 调用C#工程的 dll , 互相调用方法
- 打通 C++ 和 C# 关于 COM 组件互相调用的任督二脉
- C#托管代码与C++非托管代码互相调用
- C#托管代码与C++非托管代码互相调用
- Android 平台C# 与C++之间的互相调用方法
- C#托管代码与C++非托管代码互相调用
- C#托管代码与C++非托管代码互相调用1
- C#托管代码与C++非托管代码互相调用一(C#调用C++代码&.net 代码安全)
- C#与C++代码互相调用
- C#托管代码与C++非托管代码互相调用一(C#调用C++代码&.net 代码安全)
- C#托管代码与C++非托管代码互相调用一(C#调用C++代码&.net 代码安全)