🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: be.comp.programming
3 messages
3 total messages Started by Ivan Van den Bossche Sun, 20 Jul 2003 18:18
Delphi DLL en C toepassing
#4646
Author: Ivan Van den Bossche
Date: Sun, 20 Jul 2003 18:18
10 lines
1562 bytes
Hi,

Ik heb een DLL geschreven in Delphi.  Deze DLL wil ik gebruiken in een C
toepassing.  Een van de functies in de DLL moet een array van strings
teruggeven als resultaat.  Weet er iemand hoe je dit moet doen zodat deze
functie vanuit een C toepassing aangesproken kan worden?  Of kan er iemand
een goede website geven of een goed voorbeeld?

Bedankt
Ivan
Re: Delphi DLL en C toepassing
#4649
Author: Matthijs Laan
Date: Sun, 20 Jul 2003 23:46
137 lines
4264 bytes
Ivan Van den Bossche wrote:

> Ik heb een DLL geschreven in Delphi.  Deze DLL wil ik gebruiken in een
> C toepassing.  Een van de functies in de DLL moet een array van
> strings teruggeven als resultaat.  Weet er iemand hoe je dit moet doen
> zodat deze functie vanuit een C toepassing aangesproken kan worden? 
> Of kan er iemand een goede website geven of een goed voorbeeld?

Zoals in de standaard waarschuwing staat die Delphi in een nieuw DLL-
project zet, kan je geen Delphi-strings gebruiken in de interface, dus je 
zult het met PChar's moeten doen.

Een ander issue is hoe je memory management gaat doen: alloceert en freet 
de code in de DLL het geheugen of de code die de DLL aanroept?

Wat nu volgt is een voorbeeld waarbij de DLL het geheugen alloct en freet. 
Dit werkt met Delphi 5 en Microsoft Visual C++ 6. Als je een andere C 
compiler gebruikt moet je de import library misschien op een andere manier 
maken.

Het maken van alles gaat als volgt:

; delphi_dll.dll maken (Delphi 5)
dcc32 delphi_dll.dpr

; C import library maken (Visual C++)
lib /def:delphi_dll.def

; C prog maken (Visual C++)
cl call_delphi_dll.c delphi_dll.lib

Als je dan "call_delphi_dll.exe" runt, dan moet de output zijn:

Array size: 2
Array item 0: foo
Array item 1: foobar
Array freed

Nu de files:

--- 8< --- delphi_dll.dpr --- 8< ---

library delphi_dll;

type
  PInteger = ^Integer;

  PPCharArray = ^TPCharArray;
  TPCharArray = array[0..High(Integer) div SizeOf(PChar) - 1] of PChar;

{ Geeft als resultaat een array met PChars. In Count wordt de lengte van de
  array gezet.

  FIXME EOutOfMemory exception handlen
}
function GetStringArray(Count: PInteger): PPCharArray; cdecl;
var
  s1, s2: string;
begin
  s1 := 'foo';
  s2 := 'foobar';

  GetMem(Result, 2 * SizeOf(PChar));
  Count^ := 2;

  { Ook ruimte voor nul-terminator }
  GetMem(Result^[0], Length(s1) + 1);

  { Een Delphi-string heeft altijd een nul-karakter na het laatste
    karakter }
  Move(s1[1], Result^[0]^, Length(s1) + 1);

  GetMem(Result^[1], Length(s2) + 1);
  Move(s2[1], Result^[1]^, Length(s2) + 1);
end;

procedure FreeStringArray(p: PPCharArray; Count: integer); cdecl;
var
  i: integer;
begin
  for i := 0 to Count - 1 do begin
    FreeMem(p^[i]);
  end;
  FreeMem(p);
end;

exports
  GetStringArray,
  FreeStringArray;

begin
end.

--- 8< --- delphi_dll.h --- 8< ---

#ifndef __DELPHI_DLL__
#define __DELPHI_DLL__

char **GetStringArray(int *Count);
void FreeStringArray(char **p, int Count);

#endif/*__DLL_1__*/

--- 8< --- delphi_dll.def --- 8< ---

EXPORTS
  GetStringArray=_GetStringArray
  FreeStringArray=_FreeStringArray

--- 8< --- call_delphi_dll.c --- 8< ---

#include "delphi_dll.h"

int main() {
	int i, count;
	char **array;

	array = GetStringArray(&count);

	printf("Array size: %d\n", count);

	for(i=0;i<count;i++) {
		printf("Array item %d: %s\n", i, array[i]);
	}

	FreeStringArray(array, count);

	printf("Array freed\n");

	return 0;
}

--- 8< --- 

mvg,

Matthijs
Re: Delphi DLL en C toepassing
#4650
Author: Ivan Van den Bossche
Date: Mon, 21 Jul 2003 09:00
147 lines
4864 bytes
Hi,

Hartelijk dank voor jouw hulp.  Het is gelukt!

Groeten,
Ivan

"Matthijs Laan" <matthijsln@nospam-remove.xs4all.nl> wrote in message
news:Xns93BF1244E5B5Amatthijsln@news.xs4all.nl...
> Ivan Van den Bossche wrote:
>
> > Ik heb een DLL geschreven in Delphi.  Deze DLL wil ik gebruiken in een
> > C toepassing.  Een van de functies in de DLL moet een array van
> > strings teruggeven als resultaat.  Weet er iemand hoe je dit moet doen
> > zodat deze functie vanuit een C toepassing aangesproken kan worden?
> > Of kan er iemand een goede website geven of een goed voorbeeld?
>
> Zoals in de standaard waarschuwing staat die Delphi in een nieuw DLL-
> project zet, kan je geen Delphi-strings gebruiken in de interface, dus je
> zult het met PChar's moeten doen.
>
> Een ander issue is hoe je memory management gaat doen: alloceert en freet
> de code in de DLL het geheugen of de code die de DLL aanroept?
>
> Wat nu volgt is een voorbeeld waarbij de DLL het geheugen alloct en freet.
> Dit werkt met Delphi 5 en Microsoft Visual C++ 6. Als je een andere C
> compiler gebruikt moet je de import library misschien op een andere manier
> maken.
>
> Het maken van alles gaat als volgt:
>
> ; delphi_dll.dll maken (Delphi 5)
> dcc32 delphi_dll.dpr
>
> ; C import library maken (Visual C++)
> lib /def:delphi_dll.def
>
> ; C prog maken (Visual C++)
> cl call_delphi_dll.c delphi_dll.lib
>
> Als je dan "call_delphi_dll.exe" runt, dan moet de output zijn:
>
> Array size: 2
> Array item 0: foo
> Array item 1: foobar
> Array freed
>
> Nu de files:
>
> --- 8< --- delphi_dll.dpr --- 8< ---
>
> library delphi_dll;
>
> type
>   PInteger = ^Integer;
>
>   PPCharArray = ^TPCharArray;
>   TPCharArray = array[0..High(Integer) div SizeOf(PChar) - 1] of PChar;
>
> { Geeft als resultaat een array met PChars. In Count wordt de lengte van
de
>   array gezet.
>
>   FIXME EOutOfMemory exception handlen
> }
> function GetStringArray(Count: PInteger): PPCharArray; cdecl;
> var
>   s1, s2: string;
> begin
>   s1 := 'foo';
>   s2 := 'foobar';
>
>   GetMem(Result, 2 * SizeOf(PChar));
>   Count^ := 2;
>
>   { Ook ruimte voor nul-terminator }
>   GetMem(Result^[0], Length(s1) + 1);
>
>   { Een Delphi-string heeft altijd een nul-karakter na het laatste
>     karakter }
>   Move(s1[1], Result^[0]^, Length(s1) + 1);
>
>   GetMem(Result^[1], Length(s2) + 1);
>   Move(s2[1], Result^[1]^, Length(s2) + 1);
> end;
>
> procedure FreeStringArray(p: PPCharArray; Count: integer); cdecl;
> var
>   i: integer;
> begin
>   for i := 0 to Count - 1 do begin
>     FreeMem(p^[i]);
>   end;
>   FreeMem(p);
> end;
>
> exports
>   GetStringArray,
>   FreeStringArray;
>
> begin
> end.
>
> --- 8< --- delphi_dll.h --- 8< ---
>
> #ifndef __DELPHI_DLL__
> #define __DELPHI_DLL__
>
> char **GetStringArray(int *Count);
> void FreeStringArray(char **p, int Count);
>
> #endif/*__DLL_1__*/
>
> --- 8< --- delphi_dll.def --- 8< ---
>
> EXPORTS
>   GetStringArray=_GetStringArray
>   FreeStringArray=_FreeStringArray
>
> --- 8< --- call_delphi_dll.c --- 8< ---
>
> #include "delphi_dll.h"
>
> int main() {
> int i, count;
> char **array;
>
> array = GetStringArray(&count);
>
> printf("Array size: %d\n", count);
>
> for(i=0;i<count;i++) {
> printf("Array item %d: %s\n", i, array[i]);
> }
>
> FreeStringArray(array, count);
>
> printf("Array freed\n");
>
> return 0;
> }
>
> --- 8< ---
>
> mvg,
>
> Matthijs
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads