www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Strange Behavior

reply Peter Wood <pwood iel.ie> writes:
Can anybody please tell me why the following code behaves the way it does. I'm
working on Windows and trying to hook into the Firebird database library
(version 1.5). The code I have included is supposed to try and create a new
database file. When I execute this for the first time (i.e. when the database
file does not exist) it creates the database and the output seems to indicate
that it was successful but it tells me there was an error. When I execute it a
second or subsequent time the output seems to say that it should fail the
success test but it doesn't.

To get this to work you must have a copy of the fbclient.dll file in the local
directory. This is part of a larger piece of code that I am working on but I
have cut it to a single file for demonstration purposes. Any ideas?



import std.string;

extern (C) alias long (*execute_immediate)(long *,
                                           void **,
                                           void **,
                                           ushort,
                                           char *,
                                           ushort,
                                           void *);

extern(Windows)
{
   void *LoadLibraryA(char *);
   int FreeLibrary(void *);
   void *GetProcAddress(void *, char *);
}

int main(char[][] arguments)
{
   void *library = LoadLibraryA("fbclient.dll");

   if(!(library is null))
   {
      execute_immediate func = null;

      // Fetch the function reference.
      func = cast(execute_immediate)GetProcAddress(library,
                                                  
"isc_dsql_execute_immediate");
      if(!(func is null))
      {
         long[20] status;
         ushort   dialect     = 3;
         void*    database    = null,
                  transaction = null,
                  last        = null;
         char[]   sql         = "CREATE DATABASE \"test.fdb\" USER " ~
                                "\"SYSDBA\" PASSWORD \"masterkey\"";

         func(&status[0], &database, &transaction, 0, toStringz(sql),
              dialect, last);

         printf("Status[0] = %ld, Status[1] = %ld\n", status[0], status[1]);
         if(status[0] == 1 && status[1] > 0)
            printf("ERROR: Database create failed.");
         else
            printf("Database created.\n");
      }
      else
         printf("Failed to load function reference.\n");

      FreeLibrary(library);
   }
   else
      printf("Failed to load fbclient.dll\n");

   return(0);
}
May 20 2004
parent "C. Sauls" <ibisbasenji yahoo.com> writes:
A couple of things that may help, one now, and one in general.  Although 
I don't think I know your error, sorry.

Peter Wood wrote:
 import std.string;
 
 extern (C) alias long (*execute_immediate)(long *,
                                            void **,
                                            void **,
                                            ushort,
                                            char *,
                                            ushort,
                                            void *);

Changes this to: extern (C) alias long function(long*, void**, void**, ushort, char*, ushort, void*) execute_immediate; As far as I know, C-style function pointer syntax is a no-no in D. I could be wrong though.
 extern(Windows)
 {
    void *LoadLibraryA(char *);
    int FreeLibrary(void *);
    void *GetProcAddress(void *, char *);
 }
 
 int main(char[][] arguments)
 {
    void *library = LoadLibraryA("fbclient.dll");
 
    if(!(library is null))
    {
       execute_immediate func = null;
 
       // Fetch the function reference.
       func = cast(execute_immediate)GetProcAddress(library,
                                                   
"isc_dsql_execute_immediate");
       if(!(func is null))
       {
          long[20] status;
          ushort   dialect     = 3;
          void*    database    = null,
                   transaction = null,
                   last        = null;
          char[]   sql         = "CREATE DATABASE \"test.fdb\" USER " ~
                                 "\"SYSDBA\" PASSWORD \"masterkey\"";

For sql you could take advantage of D's wysiwyg string literals and implicit concatenation of literals. Ie, change that line to: char[] sql = `CREATE DATABASE "text.fdb"` ` USER "SYSDBA"` ` PASSWORD "masterkey"`;
          func(&status[0], &database, &transaction, 0, toStringz(sql),
               dialect, last);
 
          printf("Status[0] = %ld, Status[1] = %ld\n", status[0], status[1]);
          if(status[0] == 1 && status[1] > 0)
             printf("ERROR: Database create failed.");
          else
             printf("Database created.\n");
       }
       else
          printf("Failed to load function reference.\n");
 
       FreeLibrary(library);
    }
    else
       printf("Failed to load fbclient.dll\n");
 
    return(0);
 }
 

I really don't see any error in your code itself... but I'm also not personally familiar with Firebird so there might be some quirk that's beyond me. -C. Sauls -Invironz
May 20 2004