Reputation: 2281
in mine project i have a Windows application and a dll. I have wrote dll so:
library MyDLL;
uses
System.SysUtils,
System.Classes;
{$R *.res}
function Prova: string; export;
begin
result := 'prova';
end;
exports Prova;
begin
end.
and in main program i have called routine so:
unit FrmMain;
interface
uses
// declaration uses //
function Prova: string; external 'MyDLL.dll';
type
// declaration type //
implementation
begin
...
TAdvEdit1.Text := Prova; // [1] //
...
end;
end.
When i compile all project not is reported error, and status report SUCCESS, but application not start. If i remove the line [1] then it works correctly. In general, application not start when i call the function Prova. What i can solve this problem? Thanks very much.
Upvotes: 1
Views: 2208
Reputation: 612954
The behaviour you describe is what happens when your application fails to load. When run from the debugger you get a silent failure. When run without a debugger you will see an error message, "Application failed to initialize...". This will give details.
In your case it seems that the likely cause is that the dependency of the DLL cannot be resolved by the library loader. That's why the app runs when the call to the external function is removed. When you remove that call, you also remove the dependency on the external DLL. Solve the problem by making sure the DLL can be loaded. For example place it in the same directory as the executable.
The silent failure from the debugger is rather frustrating. Once you have experienced it a few times you'll know what to do - run without the debugger to find out what's really going wrong.
I also recommend that you don't pass managed Delphi strings across module boundaries. That will force you to use the same compiler for both executable and DLL. If you are going to accept that constraint then you may as well use packages. As your code stands, it would need to use ShareMem to work. But I don't recommend that.
Upvotes: 3
Reputation: 2488
Your program and your DLL have separate memory manager. As a general rule memory allocated from DLL should not be used inside your application (the opposite is also true). Where the allocation comes from? In Delphi "string" is managed type i.e. when you assign some text to a string variable (in your case result := 'prova'), Delphi (behind the scene) allocates memory for that string using DLL's memory manager. Then, for example, if you assign other text value within your main application, the reallocation uses application's memory manager which is bad i.e. app's MM is touching memory that it hasn't allocated itself.
To solve this issue you have to include "SimpleShareMem" (Delphi >= 2010 IIRC?) unit as the first unit of your USES clause in the application (.dpr file) AND in the DLL:
library MyDLL;
uses
SimpleShareMem, // **MUST BE THE FIRST UNIT**
System.SysUtils,
System.Classes;
...
program YourApp;
uses
SimpleShareMem, // **MUST BE THE FIRST UNIT**
// declaration uses //
An example of this approach can be found in "Start > Programs > Embarcadero RAD Studio > Samples > Delphi > RTL > SimpleShareMem"
You can also use PCHAR to transfers strings between DLL and the APP.
Upvotes: 2