www.digitalmars.com         C & C++   DMDScript  

D - win32 Api Calling

reply Lewis <dethbomb hotmail.com> writes:
i made the following code to try to figure out how api calls are made in 
windows from D, but no matter what i try the type checking wont allow me 
to call it. the Docs sugest that you can use the .append(0) to add a 
null at the end of a string, but it wouldnt let me do that either... 
either way could anyone give me some tips on which direction to go with 
this code...

import std.c.stdio;

extern (Windows): private void *GetComputerName(uint *lpBuffer,uint nSize);

int main( char [] [] args ) {

	char[] newname = new char[254];
	 newname =  newname ~ "\n";

   if  (GetComputerName((uint) *newname, (uint)255))
     {
         printf("%s\n",newname);
    }

	return 1;
}


thanks for any help
Dec 12 2003
next sibling parent reply "Walter" <walter digitalmars.com> writes:
Try the following version:

import std.c.stdio;

extern (Windows): int GetComputerNameA(char *lpBuffer,uint nSize);

int main( char [] [] args ) {

char[] newname = new char[255];

   if  (GetComputerNameA(newname, newname.length))
     {
         printf("%.*s\n",newname);
    }

return 1;
}
Dec 12 2003
parent reply Lewis <dethbomb hotmail.com> writes:
Walter wrote:

 Try the following version:
 
 import std.c.stdio;
 
 extern (Windows): int GetComputerNameA(char *lpBuffer,uint nSize);
 
 int main( char [] [] args ) {
 
 char[] newname = new char[255];
 
    if  (GetComputerNameA(newname, newname.length))
      {
          printf("%.*s\n",newname);
     }
 
 return 1;
 }
 
 

thanks walter, you've saved me from running screaming back to vb :) Once i can get a feel for the syntax more, and how things work i think ill be ok... ive programmed for years, just not in this type of language.
Dec 12 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Lewis" <dethbomb hotmail.com> wrote in message
news:brds73$1g41$1 digitaldaemon.com...
 thanks walter, you've saved me from running screaming back to vb :)
 Once i can get a feel for the syntax more, and how things work i think
 ill be ok... ive programmed for years, just not in this type of language.

It's a big change going from an untyped language to a typed one. Good luck!
Dec 12 2003
parent reply Lewis <dethbomb hotmail.com> writes:
extern (Windows): int GetComputerNameA(char *lpBuffer,uint nSize);

int main( char [] [] args ) {
char[] newname = new char[255];
    if  (GetComputerNameA(newname, newname.length))
      {
          printf("%.*s\n",newname);
      }
return 1;
}

well unfortunatly that code gives an memory access error, but i have
managed to get it to run, but i get the following error...
Error 42: Symbol Undefined _GetComputerNameA 12
--- errorlevel 1

does that mean it couldnt find the function address in the dll?

after 12 hours of trying to get D to print my computer name out, im 
certain i have a long road ahead :) however, im persistent an stubborn ;o)
Dec 13 2003
next sibling parent "Charles" <sanders-consulting comcast.net> writes:
however, im persistent an stubborn ;o)
"Lewis" <dethbomb hotmail.com> wrote in message
news:breiub$7a2$2 digitaldaemon.com...
 extern (Windows): int GetComputerNameA(char *lpBuffer,uint nSize);

 int main( char [] [] args ) {
 char[] newname = new char[255];
     if  (GetComputerNameA(newname, newname.length))
       {
           printf("%.*s\n",newname);
       }
 return 1;
 }

 well unfortunatly that code gives an memory access error, but i have
 managed to get it to run, but i get the following error...
 Error 42: Symbol Undefined _GetComputerNameA 12
 --- errorlevel 1

 does that mean it couldnt find the function address in the dll?

 after 12 hours of trying to get D to print my computer name out, im
 certain i have a long road ahead :) however, im persistent an stubborn ;o)

Dec 13 2003
prev sibling next sibling parent "Charles" <sanders-consulting comcast.net> writes:
 however, im persistent an stubborn ;o)

Thats what it takes! There is a very good win32 wrapper at http://hp.vector.co.jp/authors/VA028375/contents/D_windows.h.html Also you will need to link against a 'stub' library , GetComputerName is kernel.lib, link against it ( just specfiy its name on the command line, dmd foo.d kernel.lib ) Welcome to D ! C "Lewis" <dethbomb hotmail.com> wrote in message news:breiub$7a2$2 digitaldaemon.com...
 extern (Windows): int GetComputerNameA(char *lpBuffer,uint nSize);

 int main( char [] [] args ) {
 char[] newname = new char[255];
     if  (GetComputerNameA(newname, newname.length))
       {
           printf("%.*s\n",newname);
       }
 return 1;
 }

 well unfortunatly that code gives an memory access error, but i have
 managed to get it to run, but i get the following error...
 Error 42: Symbol Undefined _GetComputerNameA 12
 --- errorlevel 1

 does that mean it couldnt find the function address in the dll?

 after 12 hours of trying to get D to print my computer name out, im
 certain i have a long road ahead :) however, im persistent an stubborn ;o)

Dec 13 2003
prev sibling parent "Walter" <walter digitalmars.com> writes:
"Lewis" <dethbomb hotmail.com> wrote in message
news:breiub$7a2$2 digitaldaemon.com...
 well unfortunatly that code gives an memory access error, but i have

Oops, had the second parameter declaration wrong. extern (Windows): int GetComputerNameA(char *lpBuffer,uint* nSize); int main( char [] [] args ) { char[] newname = new char[255]; uint length; length = newname.length; if (GetComputerNameA(newname, &length)) { printf("%.*s\n",newname[0 .. length]); } return 1; }
 managed to get it to run, but i get the following error...
 Error 42: Symbol Undefined _GetComputerNameA 12
 --- errorlevel 1
 does that mean it couldnt find the function address in the dll?

The linker doesn't look at dll's. It looks at .lib files. To see which lib a name is in, grep the .lib file for the name. For example, GetComputerNameA is in \dm\lib\kernel32.lib. Make sure you're linking that in.
Dec 13 2003
prev sibling parent reply Lewis <dethbomb hotmail.com> writes:
ok, somebody stop me when i get way out in left field :)
All these linker, header, libs an stuff is cause for a headache to a vb 
programmer :( ... but it slowly starting to making sense.

My assumption at the moment is that the .lib files are (somewhat) 
analagous to vb's typelib files in that they give the compiler a 
template to call the dll with? header files are all to define datatypes 
and function templates, so that the compiler can do compile time type 
checking...?

right now im attempting to see if a theory i have (that libs create a 
static link to a dll as opposed to a dynamic link) that i can define 
several dll calls once to dynamicly load a library and then store 
function pointers in public variables to the address's of the functions 
in the dll, by calling (psuedo example) "LoadLibrary("DllName")" *if not 
loaded already* and Address = LoadFunctionAddress("FunctionName")

now my question is, can i store these function address's in a delegate 
or what would be the best way? and also what are the advantages of 
dynamic loading (and linking) with windows dll's over static linking 
with "libs"?
Dec 14 2003
parent reply Lewis <dethbomb hotmail.com> writes:
WoW... it worked!! Now i only have to link to two library's and i can call
  any dll function :) I have pasted my code below for critique if someone
  has any suggestions on how to make it better... I have code my first D
  program without help :) as mickeyD's would say "Im Loving It!!"


  import std.c.stdio;

  extern (Windows): int LoadLibraryA (char *lpLibFileName);
  extern (Windows):int CallWindowProcA(int  lpPrevWndProc,int hWnd,char*
  Msg,char* wParam,int lParam);
  extern (Windows): int GetProcAddress(int hModule,char *lpProcName);
  extern (Windows):int GetModuleHandleA(char *lpModuleName);

  int main( char [] [] args ) {

      auto char[] Msg = "You Have Dynamically Loaded This MessageBox!!";
      auto char[] Title = "Cool Message Box Title";
      auto char[] LibraryName = "user32";
      auto char[] FunctionName = "MessageBoxA";
      auto int FunctionAddress;
      auto int Success;

    try {

     FunctionAddress = DynamicLoad(LibraryName,FunctionName);

    if ( FunctionAddress != 0 ) {
      Success = CallWindowProcA(FunctionAddress,0,Msg,Title,0);
    }
  }
  catch (Object e) {
      printf("%s\n",e.toString);
       }

      return 0;
  }


  int DynamicLoad(char[] LibName,char[] FuncName) {

      auto int hLib;
      int hProc;

      hLib = GetModuleHandleA(LibName);

      if ( hLib == 0 )     {
           hLib = LoadLibraryA(LibName);
      }

      if ( hLib == 0)     {
           return 0;
      }
      else      {
             hProc = GetProcAddress(hLib, FuncName);
        }

      return hProc;
   }
Dec 14 2003
parent reply "Sean L. Palmer" <palmer.sean verizon.net> writes:
Not completely general since you still have to know a priori what parameters
the function takes.  To do this for real you'd want to save and call thru
function pointers (with correct parameters!), not use int's.

I'm not sure why you have all the "auto" keywords everywhere.  That's really
only useful for class variables... nothing else has a 'destructor'.  You
shouldn't need to use auto on int's and char[]'s and such.  GC already
handles all that.

Glad you're liking D.  Now, if we can get more libraries so we don't have to
code to the Win32 api directly, that'll be great.  ;)

Sean

"Lewis" <dethbomb hotmail.com> wrote in message
news:brjjqm$1lci$3 digitaldaemon.com...
 WoW... it worked!! Now i only have to link to two library's and i can call
   any dll function :) I have pasted my code below for critique if someone
   has any suggestions on how to make it better... I have code my first D
   program without help :) as mickeyD's would say "Im Loving It!!"


   import std.c.stdio;

   extern (Windows): int LoadLibraryA (char *lpLibFileName);
   extern (Windows):int CallWindowProcA(int  lpPrevWndProc,int hWnd,char*
   Msg,char* wParam,int lParam);
   extern (Windows): int GetProcAddress(int hModule,char *lpProcName);
   extern (Windows):int GetModuleHandleA(char *lpModuleName);

   int main( char [] [] args ) {

       auto char[] Msg = "You Have Dynamically Loaded This MessageBox!!";
       auto char[] Title = "Cool Message Box Title";
       auto char[] LibraryName = "user32";
       auto char[] FunctionName = "MessageBoxA";
       auto int FunctionAddress;
       auto int Success;

     try {

      FunctionAddress = DynamicLoad(LibraryName,FunctionName);

     if ( FunctionAddress != 0 ) {
       Success = CallWindowProcA(FunctionAddress,0,Msg,Title,0);
     }
   }
   catch (Object e) {
       printf("%s\n",e.toString);
        }

       return 0;
   }


   int DynamicLoad(char[] LibName,char[] FuncName) {

       auto int hLib;
       int hProc;

       hLib = GetModuleHandleA(LibName);

       if ( hLib == 0 )     {
            hLib = LoadLibraryA(LibName);
       }

       if ( hLib == 0)     {
            return 0;
       }
       else      {
              hProc = GetProcAddress(hLib, FuncName);
         }

       return hProc;
    }

Dec 15 2003
parent Lewis <dethbomb hotmail.com> writes:
Sean L. Palmer wrote:

 Not completely general since you still have to know a priori what parameters
 the function takes.  To do this for real you'd want to save and call thru
 function pointers (with correct parameters!), not use int's.
 
 I'm not sure why you have all the "auto" keywords everywhere.  That's really
 only useful for class variables... nothing else has a 'destructor'.  You
 shouldn't need to use auto on int's and char[]'s and such.  GC already
 handles all that.
 
 Glad you're liking D.  Now, if we can get more libraries so we don't have to
 code to the Win32 api directly, that'll be great.  ;)
 
 Sean
 

Thanks for the tips! anything like that helps alot since i have alot to learn when it comes to learning how memory is managed from D, and what keywords actually do.
Dec 15 2003