c#调用托管dll如何申请非托管内存传给c++

tryatry555 2018-01-23 11:47:13
求问各位大神,在c++采用托管的方式生成一个dll,这是c++的函数:
test::test(byte** src, int fileNum,int Min)

在debug模式下,采用start debug without debug不会出错,但是在release模式下,采用start debug without debug报试图访问被保护的内存的错误。怀疑是在release情况下,test函数在运行的情况下,c#端的资源因为是托管,被GC回收了。
在c#端我是用fixed的方法获取指针,如下:
byte*[] result = new byte * [len];
for(){
//.......
fixed (byte* p = &re[0])
{
result[k] = p;
}
}
}
fixed (byte** pData = result)
{
return pData;
}

请问在c#端如何将资源存储的内存改变为非托管,然后传给c++?
...全文
462 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
真相重于对错 2018-01-25
  • 打赏
  • 举报
回复
把一个指针传给一个函数,相对于把一个值直接传给函数区别就是。 打一个不恰当的比喻 传指针相当于把一个银行账号告诉你,告诉你之前,可能里面有100w存款,但是你接受后,去取钱却发现被人提光了 而传一个值 相当于直接给你100w现金 另外看了你的代码,似乎你要给c++传一个byte二维数组,直接写就可以c++可以直接接受。语法有些不一样,具体查c++/clr数组语法,我记不太清楚了
真相重于对错 2018-01-25
  • 打赏
  • 举报
回复
1、非托管的东西,除非你明确收回,或者程序结束,它一直就在那里 2、所谓byte** ,c#也不是非托管的,*操作必须跟fixed(大概是这个单词)结合代表“钉住”,C#等。net的东西要用到非托管的内存应该用intptr C++/clr比较复杂,你可以在一个代码里面包含托管和非托管的内容。大部分会自动转换,但是也有个别情况 具体请查msdn关于“平台操作部分”。
tryatry555 2018-01-25
  • 打赏
  • 举报
回复
引用 3 楼 hdt 的回复:
c++也是托管的,你怎么会用到非托管内存?
在c#wo传一个byte**给c++,release模式下debug没有错误,start without debug下出错了,是在读取c#传过来的值时错误,所以我猜测会不会是因为c#那边的托管资源被GC回收了,导致c++这边出错了
tryatry555 2018-01-25
  • 打赏
  • 举报
回复
引用 5 楼 From_TaiWan 的回复:
[quote=引用 4 楼 From_TaiWan 的回复:] 托管的dll,不需要非托管内存地址吧 尝试添加引用,using,没测试过,供参考 在C#里面产生一个非托管变量可以这样

byte[] in_Src = new byte[3] { 123, 5, 255 };
GCHandle in_Src_C = GCHandle.Alloc(in_Src, GCHandleType.Pinned);

这样,in_Src_C就是一个不被GC回收的变量 用完,要及时in_Src_C.Free();接下来它又受GC管理了 [/quote] C++那边函数的入口是
CTextureCycle(byte* srcFilePixe[], int fileNum, int srcFileWidth, int srcFileHeight, int Min_loop_count)
我该怎么把这个非托管的值传进去
tryatry555 2018-01-25
  • 打赏
  • 举报
回复
	CTextureCycle::CTextureCycle(byte* srcFilePixe[], int fileNum, int srcFileWidth, int srcFileHeight, int Min_loop_count) {	
		this->srcWidth = srcFileWidth;
		this->srcHeight = srcFileHeight;
		this->srcLen = srcFileWidth * srcFileHeight * 3;
		this->imageNum = fileNum;
		this->min_loop_count = Min_loop_count;
		int n;
//		CImage * myImage;
		this->imageArray = new CImage[fileNum];
		this->orgFabricArray = new byte*[fileNum];
//		cout << fileNum << endl;
		byte * currentPointer;
		for (int k = 0; k < fileNum; k++)
		{
			orgFabricArray[k] = new byte[this->srcLen];
			
			this->imageArray[k].Create(srcFileWidth, srcFileHeight, 24);
			currentPointer = srcFilePixe[k];
			cout << "this->srcLen = " << this->srcLen << endl;
			for (int i = 0; i < this->srcLen; i++)
			{	
				//if (IsBadReadPtr(currentPointer, 1)){ currentPointer++; continue;};
				orgFabricArray[k][i] = *currentPointer;//release模式下debug不报错,start without debug运行到一半报错 
				currentPointer++;
//				orgFabricArray[k][i] = msg[k][i];		
			}
			n = 0;
			for (int i = 0; i < srcFileWidth; i++)
			{
				for (int j = 0; j < srcFileHeight; j++)
				{
					this->imageArray[k].SetPixelRGB(i, j, orgFabricArray[k][n], orgFabricArray[k][n + 1], orgFabricArray[k][n + 2]);
				   	n = n + 3;
				}
			}	
		}
	}
tryatry555 2018-01-25
  • 打赏
  • 举报
回复
可以了,按照10楼的方法,把指针换成CLR数组就可以了
秋的红果实 2018-01-25
  • 打赏
  • 举报
回复
托管的,请尝试#4
秋的红果实 2018-01-25
  • 打赏
  • 举报
回复
如果是非托管的dll

[DllImport("XXX.dll")]
public static extern void CTextureCycle([MarshalAs(UnmanagedType.LPTStr)]out byte[] srcFilePixe, int fileNum, int srcFileWidth, int srcFileHeight, int Min_loop_count);

调用时,第一个参数 byte[] srcFilePixe=...; 不行,请追问
秋的红果实 2018-01-24
  • 打赏
  • 举报
回复
引用 4 楼 From_TaiWan 的回复:
托管的dll,不需要非托管内存地址吧 尝试添加引用,using,没测试过,供参考 在C#里面产生一个非托管变量可以这样

byte[] in_Src = new byte[3] { 123, 5, 255 };
GCHandle in_Src_C = GCHandle.Alloc(in_Src, GCHandleType.Pinned);

这样,in_Src_C就是一个不被GC回收的变量 用完,要及时in_Src_C.Free();接下来它又受GC管理了
秋的红果实 2018-01-24
  • 打赏
  • 举报
回复
托管的dll,不需要非托管内存地址吧 尝试添加引用,using,没测试过,供参考 在C#里面产生一个非托管变量可以这样

byte[] in_Src = new byte[3] { 123, 5, 255 };
GCHandle in_Src_C = GCHandle.Alloc(in_Src, GCHandleType.Pinned);

真相重于对错 2018-01-24
  • 打赏
  • 举报
回复
c++也是托管的,你怎么会用到非托管内存?
tryatry555 2018-01-24
  • 打赏
  • 举报
回复
引用 1 楼 kampoo 的回复:
托管内存会被回收,在传递给c++代码调用时需要分配非回收内存 或者 标记不要回收,在c++调用返回后托管销毁。
请问如何标志为不要回收,需要传给c++的是byte**,请问如何将这个值标志为不要回收
kampoo 2018-01-23
  • 打赏
  • 举报
回复
托管内存会被回收,在传递给c++代码调用时需要分配非回收内存 或者 标记不要回收,在c++调用返回后托管销毁。

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧