托管函数和非托管函数如何互相传递ansi字符串?

本文介绍在托管代码(.NET Framework)与非托管代码(C/C++)间如何传递字符串。主要包括两部分内容:从托管代码向非托管代码传递字符串,以及从非托管代码向托管代码传递字符串。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先来介绍两个预处理指令:

#pragma unmanaged

#pragma managed

这两个预处理指令,控制函数编译成托管函数,还是非托管函数。是函数级别的预控制指令。

1. 托管函数传送字符串给非托管函数

分三步走

a.先调用StringToHGlobalAnsi将string转换成IntPtr类型变量,(IntPtr是Net framework用于表示指针或句柄的平台特定类型。) 这个转换过程就是将托管 String 中的内容复制到非托管内存,并在复制时转换为 ANSI 格式。此处,并不是将托管内存传递出来,而是,在非托管堆中分配内存并返回地址。所以,这块内存需要自己释放。

b.通过ToPointer方法将IntPtr实例的值转换为指向未指定的类型的指针(void *)。

c.使用完后调用FreeHGlobal 释放a步中的非托管内存。

看一个完整的例子:

// MarshalANSI1.cpp
// compile with: /clr
#include <iostream>
#include 
<stdio.h>

using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;

#pragma unmanaged

void NativeTakesAString(const char* p) {
   printf_s(
"(native) received '%s'\n", p);
}

#pragma managed

int main() {
   String
^ s = gcnew String("sample string");
   IntPtr ip 
= Marshal::StringToHGlobalAnsi(s);
   
const char* str = static_cast<const char*>(ip.ToPointer());

   Console::WriteLine(
"(managed) passing stringdot.gif");
   NativeTakesAString( str );

   Marshal::FreeHGlobal( ip );
}

2. 非托管函数传递字符串给托管函数

这个简单的多了。只需要调用Marshal::PtrToStringAnsi把传统的c字符串转换成托管字符串即可。

例子:

// MarshalANSI2.cpp
// compile with: /clr
#include <iostream>
#include 
<vcclr.h>

using namespace std;

using namespace System;
using namespace System::Runtime::InteropServices;

#pragma managed

void ManagedStringFunc(char* s) {
   String
^ ms = Marshal::PtrToStringAnsi(static_cast<IntPtr>(s));
   Console::WriteLine(
"(managed): received '{0}'", ms);
}

#pragma unmanaged

void NativeProvidesAString() {
   cout 
<< "(native) calling managed funcdot.gif\n";
   ManagedStringFunc(
"test string");
}

#pragma managed

int main() {
   NativeProvidesAString();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值