我在c ++中有这段代码
extern "C"
{
__declspec(dllexport) void ConvertToByte(char *filename,unsigned char* data)
{
BITMAPINFO *info;
data=(unsigned char *)LoadDIBitmap(filename, &info);
}
}
我希望从c#中提供文件名并获取数据 如何?
[DllImport("bmpToByte.dll", CharSet = CharSet.Ansi)]
public static extern void ConvertToByte(string pame,ref byte[] data);
这种方法不起作用。任何想法请帮助,因为我是编程的新手,我不知道该怎么做。谢谢 我发送了所有使用c ++的代码。也许有人有想法。请给我一些帮助。
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <memory.h>
#include <windows.h>
void *
LoadDIBitmap(char *filename, /* I - File to load */
BITMAPINFO **info) /* O - Bitmap information */
{
FILE *fp; /* Open file pointer */
void *bits; /* Bitmap pixel bits */
long bitsize, /* Size of bitmap */
infosize; /* Size of header information */
BITMAPFILEHEADER header; /* File header */
/*
* Try opening the file; use "rb" mode to read this *binary* file.
*/
if ((fp = fopen(filename, "rb")) == NULL)
return (NULL);
/*
* Read the file header and any following bitmap information…
*/
if (fread(&header, sizeof(BITMAPFILEHEADER), 1, fp) < 1)
{
/*
* Couldn't read the file header - return NULL…
*/
fclose(fp);
return (NULL);
};
if (header.bfType != 'MB') /* Check for BM reversed… */
{
/*
* Not a bitmap file - return NULL…
*/
fclose(fp);
return (NULL);
};
infosize = header.bfOffBits - sizeof(BITMAPFILEHEADER);
if ((*info = (BITMAPINFO *)malloc(infosize)) == NULL)
{
/*
* Couldn't allocate memory for bitmap info - return NULL…
*/
fclose(fp);
return (NULL);
};
if (fread(*info, 1, infosize, fp) < infosize)
{
/*
* Couldn't read the bitmap header - return NULL…
*/
free(*info);
fclose(fp);
return (NULL);
};
/*
* Now that we have all the header info read in, allocate memory for the
* bitmap and read *it* in…
*/
if ((bitsize = (*info)->bmiHeader.biSizeImage) == 0)
bitsize = ((*info)->bmiHeader.biWidth *
(*info)->bmiHeader.biBitCount + 7) / 8 *
abs((*info)->bmiHeader.biHeight);
if ((bits = malloc(bitsize)) == NULL)
{
/*
* Couldn't allocate memory - return NULL!
*/
free(*info);
fclose(fp);
return (NULL);
};
if (fread(bits, 1, bitsize, fp) < bitsize)
{
/*
* Couldn't read bitmap - free memory and return NULL!
*/
free(*info);
free(bits);
fclose(fp);
return (NULL);
};
/*
* OK, everything went fine - return the allocated bitmap…
*/
fclose(fp);
return (bits);
}
int
SaveDIBitmap(char *filename, /* I - File to save to */
BITMAPINFO *info, /* I - Bitmap information */
void *bits) /* I - Bitmap pixel bits */
{
FILE *fp; /* Open file pointer */
long size, /* Size of file */
infosize, /* Size of bitmap info */
bitsize; /* Size of bitmap pixels */
BITMAPFILEHEADER header; /* File header */
/*
* Try opening the file; use "wb" mode to write this *binary* file.
*/
if ((fp = fopen(filename, "wb")) == NULL)
return (-1);
if (info->bmiHeader.biSizeImage == 0)/* Figure out the bitmap size */
bitsize = (info->bmiHeader.biWidth *
info->bmiHeader.biBitCount + 7) / 8 *
abs(info->bmiHeader.biHeight);
else
bitsize = info->bmiHeader.biSizeImage;
infosize = sizeof(BITMAPINFOHEADER);
switch (info->bmiHeader.biCompression)
{
case BI_BITFIELDS :
infosize += 12; /* Add 3 RGB doubleword masks */
if (info->bmiHeader.biClrUsed == 0)
break;
case BI_RGB :
if (info->bmiHeader.biBitCount > 8 &&
info->bmiHeader.biClrUsed == 0)
break;
case BI_RLE8 :
case BI_RLE4 :
if (info->bmiHeader.biClrUsed == 0)
infosize += (1 << info->bmiHeader.biBitCount) * 4;
else
infosize += info->bmiHeader.biClrUsed * 4;
break;
};
size = sizeof(BITMAPFILEHEADER) + infosize + bitsize;
/*
* Write the file header, bitmap information, and bitmap pixel data…
*/
header.bfType = 'MB'; /* Non-portable… sigh */
header.bfSize = size;
header.bfReserved1 = 0;
header.bfReserved2 = 0;
header.bfOffBits = sizeof(BITMAPFILEHEADER) + infosize;
if (fwrite(&header, 1, sizeof(BITMAPFILEHEADER), fp) <
sizeof(BITMAPFILEHEADER))
{
/*
* Couldn't write the file header - return…
*/
fclose(fp);
return (-1);
};
int l;
if (l=fwrite(info, 1, infosize, fp) < infosize)
{
/*
* Couldn't write the bitmap header - return…
*/
fclose(fp);
return (-1);
};
if (l=fwrite(bits, 1, bitsize, fp) < bitsize)
{
/*
* Couldn't write the bitmap - return…
*/
fclose(fp);
return (-1);
};
/*
* OK, everything went fine - return…
*/
fclose(fp);
return (0);
}
extern "C"
{
__declspec(dllexport) void ConvertToByte(char *filename,unsigned char** data)
{
char temp[100];
sprintf(temp,filename);
BITMAPINFO *info;
*data=(unsigned char *)LoadDIBitmap(temp, &info);
}
答案 0 :(得分:2)
尝试使用:
[DllImport("bmpToByte.dll", CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.Cdecl)]
unsafe static extern void ConvertToByte(string pame,byte* data);
注意使用Cdecl calling convention:没有它,P / Invoke将假定该函数使用stdcall调用约定,并且无法清理堆栈。 (您也可以更改C函数的定义以包含__stdcall
)
然后你可以传递字节*:
byte[] data = new byte[100000]
fixed (byte* p = data)
{
ConvertToByte(..., p);
}
不幸的是,你必须确保字节数组足够大:(
答案 1 :(得分:1)
只需将ref byte[] data
更改为byte[] data
,我认为它应该有用 - 其余的看似正确。
答案 2 :(得分:1)
C ++代码不好:您正在设置data
这是ConvertToByte
函数中的参数。它没有消失。您可以将此作为起点,至少在C ++方面:
extern "C"
{
__declspec(dllexport) void ConvertToByte(char *filename,unsigned char** data)
{
BITMAPINFO *info;
*data=(unsigned char *)LoadDIBitmap(filename, &info);
}
}
这样调用者就会传入一个指向指针的指针。该函数将指针指向该指针中的图像数据。