I'm trying to learn how to write a wrapper around a DLL and I've hit a bit of a road-block. I've got a struct declared as such:
[StructLayout(LayoutKind.Sequential)]
unsafe struct SDL_Surface
{
public readonly UInt32 flags;
public readonly SDL_PixelFormat* format;
public readonly int w, h;
public readonly int pitch;
public void* pixels;
/// <summary>Application data associated with the surface</summary>
public void* userdata;
/// <summary>information needed for surfaces requiring locks</summary>
public readonly int locked;
public readonly void* lock_data;
/// <summary>clipping information</summary>
public readonly SDL_Rect clip_rect;
/// <summary>info for fast blit mapping to other surfaces</summary>
private SDL_BlitMap *map; // <--- Cannot take the address of, get the size of, or declare a pointer to a managed type
/// <summary>Reference count -- used when freeing surface</summary>
public int refcount;
}
When I try to compile my project, it gives the above error.
But you will notice above it, I do have a pointer to another struct. I'm trying to figure out what the difference between these two structs is that makes one work but the other doesn't, but I'm not sure; they're both unsafe structs. They are as follows:
[StructLayout(LayoutKind.Sequential)]
unsafe struct SDL_PixelFormat
{
UInt32 format;
SDL_Palette *palette;
byte BitsPerPixel;
byte BytesPerPixel;
fixed byte padding [2];
UInt32 Rmask;
UInt32 Gmask;
UInt32 Bmask;
UInt32 Amask;
byte Rloss;
byte Gloss;
byte Bloss;
byte Aloss;
byte Rshift;
byte Gshift;
byte Bshift;
byte Ashift;
int refcount;
SDL_PixelFormat *next;
}
unsafe internal delegate int SDL_blit(SDL_Surface* src, SDL_Rect* srcrect, SDL_Surface* dst, SDL_Rect* dstrect);
[StructLayout(LayoutKind.Sequential)]
unsafe struct SDL_BlitMap
{
SDL_Surface* dst;
int identity;
SDL_blit blit;
void* data;
SDL_BlitInfo info;
/* the version count matches the destination; mismatch indicates
an invalid mapping */
UInt32 dst_palette_version;
UInt32 src_palette_version;
}
[StructLayout(LayoutKind.Sequential)]
struct SDL_Rect
{
int x, y;
int w, h;
}
So what do I have to change to make this compile?
I believe it's the reference to SDL_blit
in SDL_BlitMap
that's causing the problem. I've declared it as a delegate; is there something else I should be declaring it as? It's defined as this, in C:
typedef int (*SDL_blit) (struct SDL_Surface * src, SDL_Rect * srcrect,
struct SDL_Surface * dst, SDL_Rect * dstrect);
Any struct that contains a managed type cannot have its address taken. Delegates are a reference type, therefore they are also a managed type. This means that an SDL_Blitmap is a managed type because it contains a managed reference to an SDL_blit, thus you cannot get a pointer to it without fixing it first.
If the function you are trying to invoke is already available in the dll, I suggest you have a look at the DllImportAttribute.(http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute(v=vs.100).aspx)
By combining a public static extern declaration with a DllImportAttribute, you can invoke any global function declared in the dll you are interop-ing.
Alternatively you'll need to create a C/C++ side function that takes a function pointer and invokes it, which could get messy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With