将 C++ 数组传递给 C# 函数
Passing a C++ array to a C# function
我正在尝试使用 C# 库轻松地将原始像素数组转换为 PNG 文件。我使用 C++ 和 OpenGL 编写了我的初始程序,因此最好的方法是使用 COM 将我的 C++ 像素数组传递给 C# dll,并使 C# dll 将它们保存为 PNG 文件。我可以轻松地将值传递给 C#,但我无法快速弄清楚如何将非托管 C++ 数组传递给 C#。我读过您可以使用 SAFEARRAYS 或进行某种封送处理和解封处理。无论如何,我不确定他们。这是我的 C# 代码,
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace PNG_Creator_DLL
{
[ComVisible(true)]
public interface IPicturesAndMovies
{
//int Add(int a, int b);
int CreatePNG(UInt16[] imagery_data);
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class PNG_Create_Class: IPicturesAndMovies
{
public int CreatePNG(UInt16[] imagery_data)
{
//create the images directory
Directory.CreateDirectory("images");
String fileName = "images\PNG_test_nmr" + "_0000.png";
var pngStream = new FileStream(fileName, FileMode.Create);
readImage(imagery_data, pngStream, 384, 288); //create the png frame
pngStream.Close();
fileName = "images\PNG_test_nmr" + "_" + "0001" + ".png";
pngStream = new FileStream(fileName, FileMode.Create);
pngStream.Close();
File.Delete(fileName);
return 0;
}
private Boolean readImage(UInt16[] imagery_data, Stream pngStream, Int32 width, Int32 height)
{
var bmp = new WriteableBitmap(width, height, 96, 96, PixelFormats.Gray16, null);
Int32 bytesPerPixel = bmp.Format.BitsPerPixel / 8;
Int32Rect drawRegionRect = new Int32Rect(0, 0, bmp.PixelWidth, bmp.PixelHeight);
Int32 stride = bmp.PixelWidth * bytesPerPixel;
bmp.WritePixels(drawRegionRect, imagery_data, stride, 0);
PngBitmapEncoder enc = new PngBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bmp));
enc.Save(pngStream);
return true;
}
}
}
这是我的 C++ 代码,它使用 COM 并尝试将数组传递给 C# dll
#include "stdafx.h"
#include <Windows.h>
#import "..\x64\Release\dllFiles\PNG_Creator_DLL.tlb" no_namespace
int main()
{
unsigned short* imagery_data = new unsigned short[384 * 288];
unsigned short temp_sum = 0;
for (int index_row = 0; index_row < 288; index_row++)
{
temp_sum = 0;
for (int index_col = 0; index_col < 384; index_col++)
{
imagery_data[index_row * 384 + index_col] = temp_sum;
temp_sum = (unsigned short)(temp_sum + 160);
}
}
CoInitialize(NULL);
IPicturesAndMoviesPtr obj;
obj.CreateInstance(__uuidof(PNG_Create_Class));
printf("Create = %d\n", obj->CreatePNG(imagery_data));
CoUninitialize();
return 0;
}
我在以下位置收到 C2664 编译器错误
printf("Create = %d\n", obj->CreatePNG(imagery_data));
它说 'long IPicturesAndMovies::CreatePNG(SAFEARRAY *)':无法将参数 1 从 'unsigned short *' 转换为 'SAFEARRAY *'
有什么解决办法吗?
按照下面的方法试试。可能有用
//YOUR ARRAY NEEDS TO BE CONVERTED TO SAFE ARRAY
unsigned short* imagery_data = new unsigned short[384 * 288];
//DECLARE A SAFE ARRAY POINTER
SAFEARRAY *psa;
//AS THE REQUIRED IS UInt16[] - USE VT_UI2
//LOWER BOUND = 0
//UPPER BOUND = 110592 (384 * 288)
psa = SafeArrayCreateVector(VT_UI2, 0, 110592); //REFER DOCUMENTATION
unsigned short *pData;
HRESULT hr = SafeArrayAccessData(psa, (void **)&pData); //REFER DOCUMENTATION
memcpy(pData, imagery_data, 110592*sizeof(unsigned short));
SafeArrayUnaccessData(psa);//REFER DOCUMENTATION
然后用psa
过关
完成使用后调用 SafeArrayDestroy
进行清理。
SafeArrayDestroy(psa);
上面的代码是从下面 link 中提取并缩短的。
我正在尝试使用 C# 库轻松地将原始像素数组转换为 PNG 文件。我使用 C++ 和 OpenGL 编写了我的初始程序,因此最好的方法是使用 COM 将我的 C++ 像素数组传递给 C# dll,并使 C# dll 将它们保存为 PNG 文件。我可以轻松地将值传递给 C#,但我无法快速弄清楚如何将非托管 C++ 数组传递给 C#。我读过您可以使用 SAFEARRAYS 或进行某种封送处理和解封处理。无论如何,我不确定他们。这是我的 C# 代码,
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace PNG_Creator_DLL
{
[ComVisible(true)]
public interface IPicturesAndMovies
{
//int Add(int a, int b);
int CreatePNG(UInt16[] imagery_data);
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class PNG_Create_Class: IPicturesAndMovies
{
public int CreatePNG(UInt16[] imagery_data)
{
//create the images directory
Directory.CreateDirectory("images");
String fileName = "images\PNG_test_nmr" + "_0000.png";
var pngStream = new FileStream(fileName, FileMode.Create);
readImage(imagery_data, pngStream, 384, 288); //create the png frame
pngStream.Close();
fileName = "images\PNG_test_nmr" + "_" + "0001" + ".png";
pngStream = new FileStream(fileName, FileMode.Create);
pngStream.Close();
File.Delete(fileName);
return 0;
}
private Boolean readImage(UInt16[] imagery_data, Stream pngStream, Int32 width, Int32 height)
{
var bmp = new WriteableBitmap(width, height, 96, 96, PixelFormats.Gray16, null);
Int32 bytesPerPixel = bmp.Format.BitsPerPixel / 8;
Int32Rect drawRegionRect = new Int32Rect(0, 0, bmp.PixelWidth, bmp.PixelHeight);
Int32 stride = bmp.PixelWidth * bytesPerPixel;
bmp.WritePixels(drawRegionRect, imagery_data, stride, 0);
PngBitmapEncoder enc = new PngBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bmp));
enc.Save(pngStream);
return true;
}
}
}
这是我的 C++ 代码,它使用 COM 并尝试将数组传递给 C# dll
#include "stdafx.h"
#include <Windows.h>
#import "..\x64\Release\dllFiles\PNG_Creator_DLL.tlb" no_namespace
int main()
{
unsigned short* imagery_data = new unsigned short[384 * 288];
unsigned short temp_sum = 0;
for (int index_row = 0; index_row < 288; index_row++)
{
temp_sum = 0;
for (int index_col = 0; index_col < 384; index_col++)
{
imagery_data[index_row * 384 + index_col] = temp_sum;
temp_sum = (unsigned short)(temp_sum + 160);
}
}
CoInitialize(NULL);
IPicturesAndMoviesPtr obj;
obj.CreateInstance(__uuidof(PNG_Create_Class));
printf("Create = %d\n", obj->CreatePNG(imagery_data));
CoUninitialize();
return 0;
}
我在以下位置收到 C2664 编译器错误 printf("Create = %d\n", obj->CreatePNG(imagery_data));
它说 'long IPicturesAndMovies::CreatePNG(SAFEARRAY *)':无法将参数 1 从 'unsigned short *' 转换为 'SAFEARRAY *'
有什么解决办法吗?
按照下面的方法试试。可能有用
//YOUR ARRAY NEEDS TO BE CONVERTED TO SAFE ARRAY
unsigned short* imagery_data = new unsigned short[384 * 288];
//DECLARE A SAFE ARRAY POINTER
SAFEARRAY *psa;
//AS THE REQUIRED IS UInt16[] - USE VT_UI2
//LOWER BOUND = 0
//UPPER BOUND = 110592 (384 * 288)
psa = SafeArrayCreateVector(VT_UI2, 0, 110592); //REFER DOCUMENTATION
unsigned short *pData;
HRESULT hr = SafeArrayAccessData(psa, (void **)&pData); //REFER DOCUMENTATION
memcpy(pData, imagery_data, 110592*sizeof(unsigned short));
SafeArrayUnaccessData(psa);//REFER DOCUMENTATION
然后用psa
过关
完成使用后调用 SafeArrayDestroy
进行清理。
SafeArrayDestroy(psa);
上面的代码是从下面 link 中提取并缩短的。