www.digitalmars.com         C & C++   DMDScript  

D - imagemagick wrapper?

reply "Mårten Ask" <majbritt37 hotmail.com> writes:
Hi,

I want to use som functions from the imagemagick C api. How do I do that?
How do I call the functions and objects and how do I link with the dll's?
Aug 12 2003
parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
here's a templated class lib I wrote to help with dll loading ('cos I like
the delphi extern "foo.dll"; )
and an example (loads winmm.dll to all access to multimedia timers)
due to D's templateing its a little verbose, but works ...

first make instances of the types of functions you want to import
e.g. `extern (windows) DWORD func();`
instance DynFunc( Windows, DWORD ) noParamReturnsDword;

the declare a func pointer to it (using the template instance)
`<instance>.fp` e.g. ....
noParamReturnsDword.fp myFunc;

// now write a static initialiser to your module to load the dll and get the
function.
// there are two ways to do this both have the same result but its personal
preference which you use
static this()
{
// fp = <template>.require( <dll name>, <func_name> ); // I perfer this
myFunc = I_I_Ldr.require( "foo.dll", "someFuncname" );
// <template>.use( fp, <dll name>, <func_name> );
noParamReturnsDword.use( myFunc,   "foo.dll", "someFuncname" );
}

for C fucntions use
instance DynFunc( C, <return_type>, <param1>, <param2> .... ) somename;
if the return type is void due to D templates you can't use
instance DynFunc( C, void, int );
instead you have to use DynProc( C, int );
or DyncProc( C ) => extern(C) void func( void );

to do it manually here the code that loads up and gets a directx d3d
interface from the function
`Direct3DCreate8` in `d3d8.dll`

extern(Windows) alias IDirect3D8 function( UINT ) start_up_fp;

IDirect3D8 loadD3DLibs() {
 HMODULE sysModule;
 sysModule = LoadLibraryA( "d3d8.dll" );   // load a dll
 FARPROC fp = GetProcAddress( sysModule, cast(char*)"Direct3DCreate8" ); //
get a function pointer
 assert(fp);
 start_up_fp dxfp = cast(start_up_fp)fp;
 return dxfp(D3D_SDK_VERSION);
}

failing all that .... use implib to convert the dll to a .lib and just write
the functions as
extern( C ) .....
or extern(Windows) .....
the linker will the link correctly against <foo>.dll if you link against the
created lib file.


"Mårten Ask" <majbritt37 hotmail.com> wrote in message
news:bhb9cs$1eq3$1 digitaldaemon.com...
 Hi,

 I want to use som functions from the imagemagick C api. How do I do that?
 How do I call the functions and objects and how do I link with the dll's?

Aug 12 2003
parent reply "Mårten Ask" <majbritt37 hotmail.com> writes:
Thanks!

I haven't had time to try it out yet..

There's still one thing that puzzles me though. Structs. how do I declare
that I want a struct from the dll? From the imagemagick api:

typedef struct _MagickWand
  MagickWand;
  ...
extern MagickExport MagickWand
  *MagickCloneWand(const MagickWand *),
  *MagickCoalesceImages(MagickWand *),
  *NewMagickWand(void);
  ...

Obviously I need to declare those functions as 'extern (C) MagickWand
NewMagickWand()' but then the compiler complains about not knowing what a
MagickWand is. Do I write 'extern (C) struct MagickWand'? Or 'extern (C)
typedef MagickWand'?



"Mike Wynn" <mike.wynn l8night.co.uk> skrev i meddelandet
news:bhbaa0$1ftb$1 digitaldaemon.com...
 here's a templated class lib I wrote to help with dll loading ('cos I like
 the delphi extern "foo.dll"; )
 and an example (loads winmm.dll to all access to multimedia timers)
 due to D's templateing its a little verbose, but works ...

 first make instances of the types of functions you want to import
 e.g. `extern (windows) DWORD func();`
 instance DynFunc( Windows, DWORD ) noParamReturnsDword;

 the declare a func pointer to it (using the template instance)
 `<instance>.fp` e.g. ....
 noParamReturnsDword.fp myFunc;

 // now write a static initialiser to your module to load the dll and get

 function.
 // there are two ways to do this both have the same result but its

 preference which you use
 static this()
 {
 // fp = <template>.require( <dll name>, <func_name> ); // I perfer this
 myFunc = I_I_Ldr.require( "foo.dll", "someFuncname" );
 // <template>.use( fp, <dll name>, <func_name> );
 noParamReturnsDword.use( myFunc,   "foo.dll", "someFuncname" );
 }

 for C fucntions use
 instance DynFunc( C, <return_type>, <param1>, <param2> .... ) somename;
 if the return type is void due to D templates you can't use
 instance DynFunc( C, void, int );
 instead you have to use DynProc( C, int );
 or DyncProc( C ) => extern(C) void func( void );

 to do it manually here the code that loads up and gets a directx d3d
 interface from the function
 `Direct3DCreate8` in `d3d8.dll`

 extern(Windows) alias IDirect3D8 function( UINT ) start_up_fp;

 IDirect3D8 loadD3DLibs() {
  HMODULE sysModule;
  sysModule = LoadLibraryA( "d3d8.dll" );   // load a dll
  FARPROC fp = GetProcAddress( sysModule, cast(char*)"Direct3DCreate8" );

 get a function pointer
  assert(fp);
  start_up_fp dxfp = cast(start_up_fp)fp;
  return dxfp(D3D_SDK_VERSION);
 }

 failing all that .... use implib to convert the dll to a .lib and just

 the functions as
 extern( C ) .....
 or extern(Windows) .....
 the linker will the link correctly against <foo>.dll if you link against

 created lib file.


 "Mårten Ask" <majbritt37 hotmail.com> wrote in message
 news:bhb9cs$1eq3$1 digitaldaemon.com...
 Hi,

 I want to use som functions from the imagemagick C api. How do I do


 How do I call the functions and objects and how do I link with the




Aug 15 2003
parent "Mike Wynn" <mike.wynn l8night.co.uk> writes:
"Mårten Ask" <majbritt37 hotmail.com> wrote in message
news:bhjaf3$348$1 digitaldaemon.com...
 Thanks!

 I haven't had time to try it out yet..

 There's still one thing that puzzles me though. Structs. how do I declare
 that I want a struct from the dll? From the imagemagick api:

the compiler only needs to know about the struct layout, this is usually in the c header some times you will find typedef struct _foo { } * ApiToken; either way the dll does not "export" the struct layout. if the dll contains a struct then I assume its struct foo { int a; } extern (C) foo in_dll; I've only every used "getProcAddress" or implicit linking I'm not sure what VC++/Windows does with dll's contain data too, guess I better read some docs might be useful!! read on about how to declare the struct;
 typedef struct _MagickWand
   MagickWand;
   ...
 extern MagickExport MagickWand
   *MagickCloneWand(const MagickWand *),
   *MagickCoalesceImages(MagickWand *),
   *NewMagickWand(void);

you need to know what the _MagicWand struct looks like .. also note the use of align. struct Foo { align(1): byte a, b; int missaligned; }; struct Foo2 { align(4): byte a, b; int aligned; align(1): byte c; int offby1; }; (the default for D and C is to align items at their size (works on CISC and RISC then)) only the functions need to be extern(C) etc extern(C) : Foo * getFooFromFoo2( Foo2* ); Foo* getContext(); etc... asfaik (Walter correct me here if I'm wrong) the only time making a struct, alias or typedef as extern(CONV) is if it contains a pointer to func that you want to have that calling convention. although is does help document the code to have extern(C) struct MyStruct { align(4): int a, b, c, d; } (implies that its for use with extern(C) funcs).
   ...

 Obviously I need to declare those functions as 'extern (C) MagickWand
 NewMagickWand()' but then the compiler complains about not knowing what a
 MagickWand is. Do I write 'extern (C) struct MagickWand'? Or 'extern (C)
 typedef MagickWand'?



 "Mike Wynn" <mike.wynn l8night.co.uk> skrev i meddelandet
 news:bhbaa0$1ftb$1 digitaldaemon.com...
 here's a templated class lib I wrote to help with dll loading ('cos I


 the delphi extern "foo.dll"; )
 and an example (loads winmm.dll to all access to multimedia timers)
 due to D's templateing its a little verbose, but works ...

 first make instances of the types of functions you want to import
 e.g. `extern (windows) DWORD func();`
 instance DynFunc( Windows, DWORD ) noParamReturnsDword;

 the declare a func pointer to it (using the template instance)
 `<instance>.fp` e.g. ....
 noParamReturnsDword.fp myFunc;

 // now write a static initialiser to your module to load the dll and get

 function.
 // there are two ways to do this both have the same result but its

 preference which you use
 static this()
 {
 // fp = <template>.require( <dll name>, <func_name> ); // I perfer this
 myFunc = I_I_Ldr.require( "foo.dll", "someFuncname" );
 // <template>.use( fp, <dll name>, <func_name> );
 noParamReturnsDword.use( myFunc,   "foo.dll", "someFuncname" );
 }

 for C fucntions use
 instance DynFunc( C, <return_type>, <param1>, <param2> .... ) somename;
 if the return type is void due to D templates you can't use
 instance DynFunc( C, void, int );
 instead you have to use DynProc( C, int );
 or DyncProc( C ) => extern(C) void func( void );

 to do it manually here the code that loads up and gets a directx d3d
 interface from the function
 `Direct3DCreate8` in `d3d8.dll`

 extern(Windows) alias IDirect3D8 function( UINT ) start_up_fp;

 IDirect3D8 loadD3DLibs() {
  HMODULE sysModule;
  sysModule = LoadLibraryA( "d3d8.dll" );   // load a dll
  FARPROC fp = GetProcAddress( sysModule, cast(char*)"Direct3DCreate8" );

 get a function pointer
  assert(fp);
  start_up_fp dxfp = cast(start_up_fp)fp;
  return dxfp(D3D_SDK_VERSION);
 }

 failing all that .... use implib to convert the dll to a .lib and just

 the functions as
 extern( C ) .....
 or extern(Windows) .....
 the linker will the link correctly against <foo>.dll if you link against

 created lib file.


 "Mårten Ask" <majbritt37 hotmail.com> wrote in message
 news:bhb9cs$1eq3$1 digitaldaemon.com...
 Hi,

 I want to use som functions from the imagemagick C api. How do I do


 How do I call the functions and objects and how do I link with the





Aug 15 2003