私は近いと思いますし、解決策はばかげているに違いありません。
次の関数を定義する C++ ネイティブ DLL があります。
DllExport bool __stdcall Open(const char* filePath, int *numFrames, void** data);
{
//creates the list of arrays here... don't worry, lifetime is managed somewhere else
//foreach item of the list:
{
BYTE* pByte = GetArray(i);
//here's where my problem lives
*(data + i * sizeofarray) = pByte;
}
*numFrames = total number of items in the list
return true;
}
基本的に、ファイル パスを指定すると、この関数はバイト配列 (BYTE*) のリストを作成し、データ パラメータを介してポインタのリストを返す必要があります。それぞれが異なるバイト配列を指しています。
C# から IntPtr の配列を渡し、個々の配列を順番にマーシャリングできるようにしたいと考えています。私が使用しているコードは次のとおりです。
[DllImport("mydll.dll",EntryPoint = "Open")]
private static extern bool MyOpen(
string filePath, out int numFrames, out IntPtr[] ptr);
internal static bool Open(
string filePath, out int numFrames, out Bitmap[] images)
{
var ptrList = new IntPtr[512];
MyOpen(filePath, out numFrames, out ptrList);
images = new Bitmap[numFrames];
var len = 100; //for sake of simplicity
for (int i=0; i<numFrames;i++)
{
var buffer = new byte[len];
Marshal.Copy(ptrList[i], buffer, 0, len);
images[i] = CreateBitmapFromBuffer(buffer, height, width);
}
return true;
}
問題は私の C++ コードにあります。*(data + i * sizeofarray) = pByte; を割り当てると、ポインターの配列が破損します...何が間違っていますか?
更新: 概念を分離するための新しいソリューションの作成を開始したところ、すでに非常に奇妙なものが見つかりました。見てみましょう:
C# コード
class Program
{
[DllImport("ArrayProvider.dll")]
private static extern bool Open(out int n, ref IntPtr[] ptr);
static void Main(string[] args)
{
int n;
var pList = new IntPtr[10];
Program.Open(out n, ref pList);
foreach (var p in pList)
{
Debug.WriteLine(p.ToInt32().ToString("X"));
}
}
}
C++ コード
#include "stdafx.h"
#define DllExport __declspec( dllexport )
extern "C" {
DllExport bool __stdcall Open(int *n, void** data)
{
return true;
}
}
ネイティブ コードへの呼び出しの前に、pList には 10 個の IntPtr.Zero 要素があります。ネイティブ呼び出しから戻った後、1 つしかありません...何か問題があります...また、void** を BYTE** に置き換えた場合にも発生します