Я использую C lib с C#. Это прототип функции, которую я хочу использовать:Использование неуправляемого C lib с C#
heatmap_render_default_to(const heatmap_t* h, unsigned char* colorbuf)
Эта функция выделяет память для colorbuf так:
colorbuf = (unsigned char*)malloc(h->w*h->h * 4);
называть свою функцию из C# Я пытался сначала создать неуправляемые памяти, как это:
string image = "";
//allocate from COM heap
Marshal.StringToCoTaskMemAnsi(image);
GCHandle gch = GCHandle.Alloc(image, GCHandleType.Pinned);
HeatMap.HeatMapWrapper.NativeMethods.Render_default_to(hmPtr, image);
Но я получаю это исключение: Exception брошенного в 0x0F17263A (E asyDLL.dll) в Test.exe: 0xC0000005: место записи нарушения доступа 0x01050000. Если для этого исключения есть обработчик, программа может быть безопасно продолжена.
Это первый случай, когда я пытаюсь интегрировать неуправляемую библиотеку в C#.
Может ли кто-нибудь помочь мне в этом?
PInvoke:
[DllImport(DLL, EntryPoint = "heatmap_render_default_to", CallingConvention = CallingConvention.Cdecl)]
public static extern string Render_default_to(IntPtr h, byte[] colorbuf);
[DllImport(DLL, EntryPoint = "heatmap_render_to", CallingConvention = CallingConvention.Cdecl)]
public static extern string Render_to(IntPtr h, IntPtr colorscheme, byte[] colorbuf);
[DllImport(DLL, EntryPoint = " heatmap_render_saturated_to", CallingConvention = CallingConvention.Cdecl)]
public static extern string Render_saturated_to(IntPtr h, IntPtr colorscheme, float saturation, byte[] colorbuf);
это C-код:
__declspec(dllexport) unsigned char* __cdecl heatmap_render_default_to(const heatmap_t* h, unsigned char* colorbuf)
{
return heatmap_render_to(h, heatmap_cs_default, colorbuf);
}
__declspec(dllexport) unsigned char* heatmap_render_to(const heatmap_t* h, const heatmap_colorscheme_t* colorscheme, unsigned char* colorbuf)
{
return heatmap_render_saturated_to(h, colorscheme, h->max > 0.0f ? h->max : 1.0f, colorbuf);
}
__declspec(dllexport) unsigned char* __cdecl heatmap_render_saturated_to(const heatmap_t* h, const heatmap_colorscheme_t* colorscheme, float saturation, unsigned char* colorbuf)
{
unsigned y;
assert(saturation > 0.0f);
/* For convenience, if no buffer is given, malloc a new one. */
if (!colorbuf) {
colorbuf = (unsigned char*)malloc(h->w*h->h * 4);
if (!colorbuf) {
return 0;
}
}
/* TODO: could actually even flatten this loop before parallelizing it. */
/* I.e., to go i = 0 ; i < h*w since I don't have any padding! (yet?) */
for (y = 0; y < h->h; ++y) {
float* bufline = h->buf + y*h->w;
unsigned char* colorline = colorbuf + 4 * y*h->w;
unsigned x;
for (x = 0; x < h->w; ++x, ++bufline) {
/* Saturate the heat value to the given saturation, and then
* normalize by that.
*/
const float val = (*bufline > saturation ? saturation : *bufline)/saturation;
/* We add 0.5 in order to do real rounding, not just dropping the
* decimal part. That way we are certain the highest value in the
* colorscheme is actually used.
*/
const size_t idx = (size_t)((float)(colorscheme->ncolors - 1)*val + 0.5f);
/* This is probably caused by a negative entry in the stamp! */
assert(val >= 0.0f);
/* This should never happen. It is likely a bug in this library. */
assert(idx < colorscheme->ncolors);
/* Just copy over the color from the colorscheme. */
memcpy(colorline, colorscheme->colors + idx * 4, 4);
colorline += 4;
}
}
return colorbuf;
}
'unsigned char *'! = 'String' –
Это странно. вы выделяете память для изображения (colorbuf param), но вы говорите, что код c mallocs. Что он? А как насчет hmptr? Показывать объявление pinvoke и весь вызывающий код – pm100
Функция [не выделяет память] (https://github.com/lucasb-eyer/heatmap/blob/99b8fa0670463e5c619c514a4805989d3c3af75e/heatmap.c#L189), если 'colorbuf' doesn 'оценивать значение false. Если вы просто передаете 'IntPtr.Zero', он должен выделить буфер ** для ** вас и вернуть указатель на него. – cubrr