Einzelnen Beitrag anzeigen

tony.huerlimann

Registriert seit: 15. Dez 2010
6 Beiträge
 
Delphi 2010 Enterprise
 
#1

load a dll at run-time

  Alt 27. Nov 2013, 14:21
Delphi-Version: 5
I have a strange problem when loading a dll at run-time into Delphi. The following correct Dephi code:

1) loads a dll (gurobi55.dll) at run-time
2) sets three pointers to three functions into the dll
3) runs the three dll functions and exits

Normally this code runs well: it reads a mathematical model from a file and
solves it by optimizing a function defined in the file. The result is then stored in a
second file 'gurobi.log' and the programm exits.

Now the file 'ALUAM.mps' defines a large model (450MB) with 3200000 variables. Normally, it is
no problem for the commercial solver Gurobi to solve such problems. However, Delphi
(XE2 and XE5, 64bit) crashed some time after calling GRBoptimize() with a FLOATING POINT ERROR.

If I run an identical code in C++ Builder (XE5, 64bit) it runs fine.
My question: Is there a fundamental difference between Delphi(Pascal) and C++ Builder
in loading and running dll Functions? Is there a memory limitation in Delphi's handling
of a dll memory storage? Or what could be the problem here?

The two complete programs are as follows (by the way these two code snippets
shows also --for the novice-- how to implement dynamically loading libraries in Windows (dll)
in Delphi AND in C++ Builder).


------------------ BEGIN DELPHI CODE XE5, 64bit compiler ---------
Delphi-Quellcode:
program GurobiTest;
{$APPTYPE CONSOLE}
uses System.SysUtils, Windows;

label QUIT;
type pAChar = pAnsiChar;
      GRBenv = pointer;
      GRBmodel = pointer;

var h:HMODULE; err:integer;
      grEnv:GRBenv;
      grLp:GRBmodel;

   GRBloadenv: function(var envP:GRBenv; logfilename:pAChar):integer; stdcall;
   GRBreadmodel: function(env:GRBenv; filename:pAChar; var mp:GRBmodel):integer; stdcall;
   GRBoptimize: function(model:GRBmodel):integer; stdcall;

begin
  h:=LoadLibrary('C:/gurobi550/win64/bin/gurobi55.dll');
  GRBloadenv := GetProcAddress(h,'GRBloadenv');
  GRBreadmodel := GetProcAddress(h,'GRBreadmodel');
  GRBoptimize := GetProcAddress(h,'GRBoptimize');

  err:= GRBloadenv(grEnv, 'gurobi.log');
  if err<>0 then goto QUIT;

  err:=GRBreadmodel(grEnv,'ALUAM.mps',grLp);
  if err<>0 then goto QUIT;

  err:= GRBoptimize(grLp);
  if err<>0 then goto QUIT;

  QUIT:
  FreeLibrary(h);
end
------------------ END DELPHI CODE -------------------------------


----------- BEGIN C++ CODE: C++ Builder XE5, 64bit compiler -------
Code:
#pragma hdrstop
#pragma argsused

#include <tchar.h>
#include <stdio.h>

#include <windows.h>

typedef void* GRBmodel;

typedef void* GRBenv;

typedef char* pAChar;

typedef int (__stdcall* sGurobi__0)(GRBenv& envp, pAChar LogFileName);
sGurobi__0 GRBloadenv;;

typedef int (__stdcall* sGurobi__1)(GRBmodel model, pAChar AttrName, GRBmodel& modelp);
sGurobi__1 GRBreadmodel;;

typedef int ( __stdcall * sGurobi__2 )(GRBmodel model);
sGurobi__2 GRBoptimize;;

int _tmain(int argc, _TCHAR* argv[])
{
   int err;
   HMODULE hdll = NULL;
   GRBenv grEnv = NULL;
   GRBmodel grLp = NULL;

   hdll = LoadLibrary("C:\\gurobi550\\win64\\bin\\gurobi55.dll");
   err=GetLastError();
   if (err) goto QUIT;

   GRBloadenv = (sGurobi__0) GetProcAddress( hdll, "GRBloadenv" );
   GRBreadmodel = (sGurobi__1) GetProcAddress(hdll,"GRBreadmodel");
   GRBoptimize = (sGurobi__2) GetProcAddress(hdll,"GRBoptimize");

   err = GRBloadenv(grEnv, "gurobi.log");
   if (err) goto QUIT;

  err = GRBreadmodel(grEnv,"ALUAM.mps",grLp);
  if (err) goto QUIT;

  err = GRBoptimize(grLp);
  if (err) goto QUIT;

QUIT:
   FreeLibrary(hdll);
   return 0;
}
-------------------------------------- END C++ CODE --------------

Thanks for help
Tony
  Mit Zitat antworten Zitat