views:

1388

answers:

3

Given this C API declaration how would it be imported to C#?

int _stdcall z4ctyget(CITY_REC *, void *);

I've been able to get this far:

   [DllImport(@"zip4_w32.dll",
        CallingConvention = CallingConvention.StdCall,
        EntryPoint = "z4ctygetSTD",
        ExactSpelling = false)]
    private extern static int z4ctygetSTD(ref CITY_REC args, void * ptr);

Naturally in C# the "void *" doesn't compile.

Some Googling indicates that it should be translated as "object." Which seems like it should work. But others indicate that "Void * is called a function pointer in C/C++ terms which in C# terms is a delegate". That doesn't make a whole lot of sense here as what would it delegate to? Some similar calls for other APIs found through Googling use other functions in the respective API. But in this API no other call would make sense.

The documentation for the call shows an example:

z4ctyget(&city, “00000”);

Which seems to show that even a static value could be passed.

It will compile with object in place of the void *. I don't know whether this is right and I haven't had an opportunity to test it (licensing issue).

+4  A: 

For the void* parameter you can just use an IntPtr

  [DllImport(@"zip4_w32.dll",
        CallingConvention = CallingConvention.StdCall,
        EntryPoint = "z4ctygetSTD",
        ExactSpelling = false)]
    private extern static int z4ctygetSTD(ref CITY_REC args, IntPtr ptr);
JaredPar
Darn you Jared, 30 seconds! Darn you straight to heck! -- =P
Erik Forbes
@Erick :) Had few quick draw wins today
JaredPar
+1  A: 

You can also use void* if you mark your class as unsafe.

It really depends on what the API is looking for in that parameter.

You can add IntPtr or Object* to get past compiler, but you will still need to pass it the correct data when you call it.

VBNight
A: 

As far as I can tell the C declaration of z4ctyget is:

int z4ctyget(CITY_REC *cityrec, char *zipcode);

The second parameter is a 5 character ANSI string representing the zip code at which you want to start your search or "00000" to start at the beginning of the file. So your declaration should be:

[DllImport(@"zip4_w32.dll", CharSet = CharSet.Ansi)]
private extern static int z4ctygetSTD(ref CITY_REC args, string zipcode);
Stephen Martin
The C declaration I showed was pulled straight from the .h file provided by USPS.
Mike Chess
The documentation from 2007 shows my declaration. In any case, the "00000" example shows that the expected input is a string (almost certainly ANSI). So my C# declaration should be what you are looking for.
Stephen Martin