场景三:现有C++原代码,包装后供C#调用。
C++的原代码,实际上可以直接编译成托管代码。MFC也好ATL也好……这样看起来在.NET中最强大的编程语言就是C++了:它不仅可以编写托管 程序,甚至可以将标准C++的代码也编译成托管程序!其实VC++最强大的地方不止如此,它还在于能够编写混合了托管和非托管的代码的程序!!!这样最大 的好处不仅可以将关键代码直接编译成非托管的代码,还可以避免被反编译。
假设现有C++代码如下:
class
UnmanagedClass
{
public
:
LPCWSTR GetPropertyA()
{
return
L
"
Hello!
"
; }
void
MethodB( LPCWSTR )
{}
}
我们只要再增加一个包装类到工程文件中:
namespace
wrapper
{
public
ref
class
ManagedClass
{
public
:
//
Allocate the native object on the C++ Heap via a constructor
ManagedClass() : m_Impl(
new
UnmanagedClass )
{}
//
Deallocate the native object on a destructor
~
ManagedClass()
{
delete m_Impl;
}
protected
:
//
Deallocate the native object on the finalizer just in case no destructor is called
!
ManagedClass()
{
delete m_Impl;
}
public
:
property String
^
get_PropertyA
{
String
^
get
()
{
return
gcnew String( m_Impl
->
GetPropertyA());
}
}
void
MethodB( String
^
theString )
{
pin_ptr
<
const
WCHAR
>
str
=
PtrToStringChars(theString);
m_Impl
->
MethodB(str);
}
private
:
UnmanagedClass
*
m_Impl;
}
;
}
然后,改变编译选项为“使用公共语言扩展 /clr”就可以了。这样,我们把代码编译成DLL文件就可以供.NET其它语言调用了。
最后,C#中可以象如下的代码一样调用C++类了:
ManagedClass mc
ManagedClass();
mc.MethoB(
Hello
string
mc.get_PropertyA;
场景四:如何在托管C++代码中混合托管和 非托管代码
很简单,只要从#pragma unmanaged编译指示开始的程序,一率编译成非托管代码;要想恢复成托管代码,只要使用#pragma managed就可以了。如:
#pragma unmanaged
#include
iostream
using
namespace
std;
template
typename T
f(T t)
{
cout
<<
t
<<
endl;
}
#pragma managed
using
namespace
System;
m(String
{
Console::WriteLine(s);
}
main()
{
f(
"
Hello
"
);
m(
"
World
"
);
}
生成exe文件后,用反编译程序查看 f 函数:
[PreserveSig, MethodImpl(MethodImplOptions.Unmanaged, MethodCodeType
MethodCodeType.Native), SuppressUnmanagedCodeSecurity]
public
static
unsafe
modopt(CallConvCdecl) f
const
sbyte
modopt(IsSignUnspecifiedByte) modopt(IsConst)
看不到源码,而方法属性标记为Unmanaged。
如果没有加上#pragma unmanaged,反编译得到的 f 函数为:
{
std.basic_ostream
<
char
,std::char_traits
<
char
>
>
.
<<
(std.
operator
<<<
struct
std::char_traits
<
char
>
>
(
*
((basic_ostream
<
char
,std::char_traits
<
char
>
>*
modopt(IsImplicitlyDereferenced)
*
)
&
__imp_std.cout), t), (basic_ostream
<
char
,std::char_traits
<
char
>
>*
modopt(IsImplicitlyDereferenced) modopt(CallConvCdecl)
*
(basic_ostream
<
char
,std::char_traits
<
char
>
>*
modopt(IsImplicitlyDereferenced))) __unep@
?
endl@std@@$$FYAAAV
?
$basic_ostream@DU
?
$char_traits@D@std@@@
1
@AAV21@@Z);
}
其中的函数内容一目了然。如果你的函数没有调用operator等不好理解的类库,那么反编译出来的代码简直和源码没差别。
场景三:现有C++原代码,包装后供C#调用。C++的原代码,实际上可以直接编译成托管代码。MFC也好ATL也好……这样看起来在.NET中最强大的编程语言就是C++了:它不仅可以编写托管 程序,甚至可以将标准C++的代码也编译成托管程序!其实VC++最强大的地方不止如此,它
基于.net开发,
托管
的便利好处自然不用再多言,垃圾回收、内存管理等等,加之强大的FCL类库作支持后盾,一般情况下我们都不会直接用到
非
托管
代码
,一些常用的底层api都已经被FCL类库进行了很好的封装,我们只需要知道用到哪一个类即可。
但是类库虽然强大,却
非
万能的,总有一些基于底层的api没有被封装,或者说程序要
调用
一些第三方的接口,一般都是c/c++的dll。就我本人所知,许多地区的医疗保险接口便都是
非
托管
代码
,如c++写的。
在这种情况之下,我们便要考虑到
托管
代码
对于
非
托管
代码
的
调用
问题了,这种技术称
[url]http://www.cnblogs.com/Jianchidaodi/archive/2009/03/11/1407270.html#1473515[/url]
[url]http://www.cnblogs.com/Jianchidaodi/archive/2009/03/11/1408661.html[/url]
C#
托管
代码
与C++
非
托管
代码
互相
调用
一(C#
调用
C++...
在最近的项目中,牵涉到项目源
代码
保密问题,由于
代码
是C#写的,容易被反编译,因此决定抽取核心算法部分使用C++编写,C++到目前为止好像还不能被很好的反编译,当然如果你是反汇编高手的话,也许还是有可能反编译。这样一来,就涉及C#
托管
代码
与C++
非
托管
代码
互相
调用
,于是调查了一些资料,顺便与大家分享一下:源
代码
下载
一. C# 中静态
调用
C++动态链接
1. 建立VC工程CppDe...
### 回答1:
C#是一种广泛使用的编程语言,也可以与C
代码
进行交互。
调用
C
代码
可以实现更高级的功能和操作。下面以一些示例
代码
来说明如何在C#中
调用
C
代码
:
首先,我们需要创建一个包含C
代码
的动态链接库(DLL)文件。C
代码
使用一种称为P/Invoke的技术来与C#进行交互。我们可以使用C语言编写我们的函数,并确保它们通过将它们标记为导出函数可供C#访问。
一旦我们有了动态链接库文件,我们就可以在C#中进行
调用
。我们需要在C#
代码
中使用DllImport属性来指定具体的DLL文件和函数。
以下是一个示例,演示如何
调用
C
代码
中的add函数:
// C
代码
// 将以下
代码
保存为一个名为c_code.c的文件
__declspec(dllexport) int add(int a, int b) {
return a + b;
```csharp
// C#
代码
// 将以下
代码
保存为一个名为Program.cs的文件
using System;
using System.Runtime.InteropServices;
class Program {
[DllImport("c_code.dll")]
public static extern int add(int a, int b);
static void Main() {
int result = add(2, 3);
Console.WriteLine("The result is: " + result);
在上述示例中,C
代码
文件c_code.c包含了一个add函数,它将两个整数相加并返回结果。然后,在C#
代码
中,我们使用DllImport属性标记了add函数,并指定了C
代码
的DLL文件名。在Main函数中,我们
调用
了add函数,并将结果打印到控制台。
通过这种方法,我们可以在C#中
调用
C
代码
并使用C
代码
中定义的函数来实现更高级的功能和操作。
### 回答2:
在C#中
调用
C
代码
的过程如下:
首先,需要将C
代码
编译为动态链接库(DLL)或共享库(SO)。这可以通过使用C语言的编译器将C
代码
编译为与目标平台相关的库文件来完成。
在C#中,可以使用Platform Invoke(P/Invoke)机制来
调用
C
代码
。P/Invoke是一种允许.NET程序与
非
托管
代码
进行交互的技术。
在C#中
调用
C
代码
需要使用[System.Runtime.InteropServices.DllImport]属性来指定C函数的名称和库文件的路径。例如,如果C函数的名称是"myFunction",并且库文件的路径是"path/to/myLibrary.dll",则可以使用以下方式
调用
C函数:
```csharp
using System.Runtime.InteropServices;
class Program
[DllImport("path/to/myLibrary.dll")]
public static extern void myFunction();
static void Main(
string
[] args)
myFunction();
在C#中定义的C函数必须与C
代码
中的函数签名一致,并且使用正确的数据类型。如果C函数返回某个类型的值,则可以在C#中将其定义为返回相应类型的extern函数。
需要注意的是,当在C#中
调用
C
代码
时,需要确保目标平台的运行时环境已经安装了C
代码
所需的依赖项。否则,可能会引发运行时错误。
在使用P/Invoke
调用
C
代码
时,还需要注意数据类型的匹配,例如将C#的字符串转换为C中的char数组等。
总的来说,通过使用P/Invoke机制,可以很方便地在C#中
调用
C
代码
,并实现C#与C之间的无缝交互。
### 回答3:
C#是一种面向对象的编程语言,而C是一种过程式的编程语言。虽然两者之间存在一些差异,但是C#是可以
调用
C
代码
的。
要在C#中
调用
C
代码
,我们首先需要用到一个叫做Platform Invoke(简称P/Invoke)的机制。P/Invoke是一个能够在C#中
调用
非
托管
代码
(如C
代码
)的功能。它通过使用DllImport特性来告诉C#需要
调用
的C函数的名称、所在的库等信息。
下面是一个简单的示例,展示了如何在C#中
调用
一个C函数:
首先,在C文件中,我们有一个名为myCFunction的函数:
#include <stdio.h>
void myCFunction()
printf("Hello from C!");
接下来,在C#中,我们需要使用DllImport特性来告诉编译器要
调用
的C函数的信息:
using System;
using System.Runtime.InteropServices;
class Program
[DllImport("myCLibrary.dll")]
public static extern void myCFunction();
static void Main(
string
[] args)
myCFunction(); //
调用
C函数
在这个示例中,我们使用了DllImport特性来指定要
调用
的C函数的库文件,函数名称等信息。然后,在C#中,我们可以直接
调用
这个C函数。
通过这种方式,我们可以在C#中
调用
任意的C函数,实现更灵活的编程。当然,在使用P/Invoke时需要遵守一定的规则和注意事项,如确保C函数的参数和返回值类型与C#中的类型匹配,避免出现类型转换错误等。