name mangeling beim Linken von .o Dateien aus GCC?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
fpGUIcoder
Beiträge: 199
Registriert: Di 20. Okt 2015, 23:13

name mangeling beim Linken von .o Dateien aus GCC?

Beitrag von fpGUIcoder »

Hallo,

ich habe gerade eine Unicode Unit erstellt, deren Funktionen in einer in C geschriebenen .o Datei stecken, die ich nun für Pascal verfügbar machen will. Ich erhalte aber bei der ersten von mir getesteten Funktion UTextToUpper(d: l_utext): l_utext; diese Fehlermeldung:

Error: Undefined Symbol: UTEXT_$$_UTEXTTOUPPER$SHORTSTRING$$SHORTSTRING

Die C Funktion ist so definiert:

Code: Alles auswählen

 
l_utext UTextToUpper( l_utext d ){
	l_utext l = d;
	if ( !DCkPt("UTextToUpper.d",d) ) return 0;
	while ( *d ){ *d = UToUpper(*d); d++; }
	return l;
}
 
Wie erreiche ich die Verlinkung so, dass ich die Funktion in Pascal verwenden kann.

Ich habe eine C/C++ Bibliothek die aus .a und vielen .o Dateien besteht. Ich will diese verwenden und in Pascal nur die öffentlichen Funktionen als Pascal Header schreiben, die .a und .o Dateien in die Unit linken und den in C/C++ existierenden Code von Freepascal aus verwenden.

Wie mache ich das?

Für das obige Beispiel habe ich mir eine Pascal Unit geschrieben, welche folgenden Aufbau hat:

Code: Alles auswählen

 
////////////////////////////////////////////////////////////////////////////////
//
//    Unicode Text Manipulation - Core file
//
//  (c) Copyright 2004 Point Mad. All rights reserved.
//
////////////////////////////////////////////////////////////////////////////////
unit utext;
 
interface
 
uses Sysutils,cTypes;
 
{$LINK utext.o}
 
const
  COMBUF_TEXT_SIZE = 255;
 
type
  l_utext = String;
  l_short = Byte;
  l_ulong = Cardinal;
 
var
  CommonBufferUText: array[0..COMBUF_TEXT_SIZE] of l_short;
 
function UTextLen( t: String ): l_ulong;
 
function UTextChr( t: l_utext; c: l_short ): l_utext;
 
function UTextRChr( t: l_utext; c: l_short ): l_utext;
function UTextCompare ( a: l_utext; b: l_utext ): Longint;
 
function UTextNCompare ( a: l_utext; b: l_utext; n: l_ulong ): Longint;
 
function UTextCaseCompare ( a: l_utext; b: l_utext ): Longint;
function UTextNCaseCompare ( a: l_utext; b: l_utext; n: l_ulong ): Longint;
function UTextSqNCaseCompare ( sq: l_utext; t: l_utext; n: l_ulong ): Longint;
function UTextCopy ( d: l_utext; s: l_utext ): l_utext;
 
function UTextNCopy ( d: l_utext; s: l_utext; n: l_ulong ): l_utext;
 
function UTextDup ( t: l_utext ): l_utext;
 
function UTextNDup ( t: l_utext; n: l_ulong ): l_utext;
 
function UTextCat ( d: l_utext; t: l_utext ): l_utext;
 
function UTextToUpper( d: l_utext ): l_utext;
 
function UTextToLower( d: l_utext ): l_utext;
 
function UToLower ( c: l_short ): l_short;
 
function UToUpper ( c: l_short ): l_short;
 
implementation
 
function UTextLen( t: String ): l_ulong;
var
  l: l_ulong;
begin
	l := Length(t);
	UTextLen := l;
end;
 
function UTextChr( t: l_utext; c: l_short ): l_utext;
var
  i: Integer;
begin
  i := 1;
  if Length(t) = 0 then UTextChr := IntToStr(0) else
  while i < length(t) do
  begin
    if t[i] = Chr(c) then
    begin
      UTextChr := IntToStr(i);
      i := Length(t);
    end;
    inc(i);
  end;
end;
 
function UTextRChr( t: l_utext; c: l_short ): l_utext;
var i: Integer;
begin
  i := Length(t);
  UTextRChr := IntToStr(0);
  while i>0 do
  begin
    if t[i] = Chr(c) then
    begin
      UTextRChr := IntToStr(i);
      i := 0;
    end;
    dec(i);
  end;
end;
 
function UTextCompare ( a: l_utext; b: l_utext ): Longint;
begin
  if a<b then UTextCompare := -1 else
  if a>b then UTextCompare := +1 else
  UTextCompare := 0;
end;
 
// Compare 2 texts a and b on length n, return 0 if identical
function UTextNCompare ( a: l_utext; b: l_utext; n: l_ulong ): Longint; external;
 
// Compare 2 texts a and b, return 0 if identical
function UTextCaseCompare ( a: l_utext; b: l_utext ): Longint; external;
 
 
// Compare 2 texts a and b on length n, return 0 if identical
function UTextNCaseCompare ( a: l_utext; b: l_utext; n: l_ulong ): Longint; external;
 
// Compare a sequence (sq,n) and a text t, return 0 if identical,
function UTextSqNCaseCompare ( sq: l_utext; t: l_utext; n: l_ulong ): Longint; external;
 
// Copy text s to text d, return d
function UTextCopy ( d: l_utext; s: l_utext ): l_utext; external;
 
// Copy text s to text d of n chars, add \0 at end ,return d
function UTextNCopy ( d: l_utext; s: l_utext; n: l_ulong ): l_utext; external;
 
// Make a copy of string t in a new memory allocation
function UTextDup ( t: l_utext ): l_utext; external;
 
// Make a copy of n chars of text t in a new memory allocation (add \0 at end)
function UTextNDup ( t: l_utext; n: l_ulong ): l_utext; external;
 
// Add text t at the text d end, text d must have enouf memory allocated
function UTextCat ( d: l_utext; t: l_utext ): l_utext; external;
 
// Transform text to upper case
function UTextToUpper( d: l_utext ): l_utext; external;
 
// Transform text to lower case
function UTextToLower( d: l_utext ): l_utext; external;
 
function UToLower ( c: l_short ): l_short; external;
 
function UToUpper ( c: l_short ): l_short; external;
 
end.
Es existiert eine C Objektdatei utext.o, die ich auch gelinkt habe. Die zugehörige C-Datei sieht so aus:

Code: Alles auswählen

 
////////////////////////////////////////////////////////////////////////////////
//
//    Unicode Text Manipulation - Core file
//
//  (c) Copyright 2004 Point Mad. All rights reserved.
//
////////////////////////////////////////////////////////////////////////////////
#include "stdio.h"
#include "stdarg.h"
#include "types.h"
#include "utext.h"
#include "dynld.h"
#include "internal.h"
#include "debug.h"
 
/**
*	NAME: CommonBufferUText
*	DESCRIPTION: This is a common buffer text, be careful with it.
*/
l_short CommonBufferUText[COMBUF_TEXT_SIZE];
 
////////////////////////////////////////////////////////////////////////////////
//	Return length of text t
l_ulong UTextLen( l_utext t )
{
	l_utext l = t;
 
	if ( !DCkPt("UTextLen.t",t) ) return 0;
 
	while ( *l ) l++;
 
	return l-t;
}
////////////////////////////////////////////////////////////////////////////////
//	Return 1st occurence of the char c in text t, if not found return 0
l_utext UTextChr( l_utext t, l_short c )
{
	if ( !DCkPt("UTextChr.t",t) ) return 0;
 
	while ( *t )
	{
		if ( *t == c ) return t;
 
		t++;
	}
 
	if ( c == 0 )
		return t;
 
	return 0;
}
////////////////////////////////////////////////////////////////////////////////
// Return Last occurence of the char c in text t, if not found return 0
l_utext UTextRChr( l_utext t, l_short c ) {
	l_utext r = 0;
	if ( !DCkPt("UTextRChr.t",t) ) return 0;
	while ( *t ) {
		if ( *t == c ) r = t;
		t++;
  }
  if ( c == 0 ) r = t;
	return r;
}
////////////////////////////////////////////////////////////////////////////////
// Compare 2 texts a and b, return 0 if identical
long UTextCompare ( l_utext a, l_utext b ) {
	if ( !DCkPt("UTextCompare.a",a) || !DCkPt("UTextCompare.b",b) ) return 0;
  while ( *a == *b ) {
	  if (!*a) return 0;
	  a++;
	  b++;
  }
	return *a-*b;
}
////////////////////////////////////////////////////////////////////////////////
// Compare 2 texts a and b on length n, return 0 if identical
long UTextNCompare ( l_utext a, l_utext b, l_ulong n ) {
	if ( !DCkPt("UTextNCompare.a",a) || !DCkPt("UTextNCompare.b",b) ) return 0;
  while ( n ) {
	  if ( *a != *b ) return *a-*b;
	  if ( !*a ) return 0;
	  a++;
	  b++;
	  n--;
  }
  return 0;
}
////////////////////////////////////////////////////////////////////////////////
// Compare 2 texts a and b, return 0 if identical
long UTextCaseCompare ( l_utext a, l_utext b ) {
	if ( !DCkPt("UTextCaseCompare.a",a) || !DCkPt("UTextCaseCompare.b",b) ) return 0;
  while ( UToLower(*a) == UToLower(*b) ) {
	  if (!*a) return 0;
	  a++;
	  b++;
  }
	return UToLower(*a)-UToLower(*b);
}
////////////////////////////////////////////////////////////////////////////////
// Compare 2 texts a and b on length n, return 0 if identical
long UTextNCaseCompare ( l_utext a, l_utext b, l_ulong n ) {
	if ( !DCkPt("UTextNCaseCompare.a",a) || !DCkPt("UTextNCaseCompare.b",b) ) return 0;
  while ( n ) {
	  if ( UToLower(*a) != UToLower(*b) ) return UToLower(*a)-UToLower(*b);
	  if ( !*a ) return 0;
	  a++;
	  b++;
	  n--;
  }
  return 0;
}
////////////////////////////////////////////////////////////////////////////////
// Compare a sequence (sq,n) and a text t, return 0 if identical,
long UTextSqNCaseCompare ( l_utext sq, l_utext t, l_ulong n ) {
	if ( !DCkPt("UTextNCaseCompare.sq",sq) || !DCkPt("UTextNCaseCompare.t",t) ) return 0;
  while ( n ) {
	  if ( tolower(*sq) != tolower(*t) ) return tolower(*sq)-tolower(*t);
	  if ( !*sq ) return 0;
	  sq++;
	  t++;
	  n--;
  }
  return *t;
}
////////////////////////////////////////////////////////////////////////////////
// Copy text s to text d, return d
l_utext UTextCopy ( l_utext d, l_utext s ) {
	l_utext l = d;
	if ( !DCkPt("UTextCopy.d",d) || !DCkPt("UTextCopy.s",s) ) return 0;
  while ( *d = *s ) {
	  s++;
	  d++;
  }
  *d = 0;
	return l;
}
////////////////////////////////////////////////////////////////////////////////
// Copy text s to text d of n chars, add \0 at end ,return d
l_utext UTextNCopy ( l_utext d, l_utext s, l_ulong n  ) {
	l_utext l = d;
	if ( !DCkPt("UTextNCopy.d",d) || !DCkPt("UTextNCopy.s",s) ) return 0;
  while ( ( *d = *s ) && n ) {
	  s++;
	  d++;
	  n--;
  }
  *d = 0;
	return l;
}
////////////////////////////////////////////////////////////////////////////////
// Make a copy of string t in a new memory allocation
l_utext UTextDup ( l_utext t ) {
	l_utext n;
	if ( !DCkPt("UTextDup.t",t) ) return NULL;
	n = (l_utext)malloc((UTextLen(t)*2)+2);
	if ( !n ) return NULL;
	return UTextCopy(n,t);
}
////////////////////////////////////////////////////////////////////////////////
// Make a copy of n chars of text t in a new memory allocation (add \0 at end)
l_utext UTextNDup ( l_utext t, l_ulong n ) {
	l_utext l;
	if ( !DCkPt("UTextNDup.t",t) ) return NULL;
	l = (l_utext)malloc((n*2)+2);
	if ( !l ) return NULL;
	return UTextNCopy(l,t,n);
}
////////////////////////////////////////////////////////////////////////////////
// Add text t at the text d end, text d must have enouf memory allocated
l_utext UTextCat ( l_utext d, l_utext t ) {
	l_utext l = d;
	if ( !DCkPt("UTextCat.d",d) || !DCkPt("UTextCat.t",t) ) return d;
	while ( *d ) d++;
	UTextCopy(d,t);
	return l;
}
////////////////////////////////////////////////////////////////////////////////
// Transform text to upper case
l_utext UTextToUpper( l_utext d ){
	l_utext l = d;
	if ( !DCkPt("UTextToUpper.d",d) ) return 0;
	while ( *d ){ *d = UToUpper(*d); d++; }
	return l;
}
////////////////////////////////////////////////////////////////////////////////
// Transform text to lower case
l_utext UTextToLower( l_utext d ){
	l_utext l = d;
	if ( !DCkPt("UTextToUpper.d",d) ) return 0;
	while ( *d ){ *d = UToLower(*d); d++; }
	return l;
}
////////////////////////////////////////////////////////////////////////////////
l_short UToLower ( l_short c ) {
	if ( c & 0xFF00 )
		return c;
	else
		return tolower(c & 0xFF);
}
////////////////////////////////////////////////////////////////////////////////
l_short UToUpper ( l_short c ) {
	if ( c & 0xFF00 )
		return c;
	else
		return toupper(c & 0xFF);
}
////////////////////////////////////////////////////////////////////////////////
void InitUText ( void ) {
	SYSEXPORT(UTextLen);
	SYSEXPORT(UTextChr);
	SYSEXPORT(UTextCompare);
	SYSEXPORT(UTextNCompare);
	SYSEXPORT(UTextCaseCompare);
	SYSEXPORT(UTextNCaseCompare);
	SYSEXPORT(UTextCopy);
	SYSEXPORT(UTextNCopy);
	SYSEXPORT(UTextDup);
	SYSEXPORT(UTextNDup);
	SYSEXPORT(UTextCat);
	SYSEXPORT(UTextRChr);
	SYSEXPORT(UTextSqNCaseCompare);
	SYSEXPORT(UTextToUpper);
	SYSEXPORT(UTextToLower);
	SYSEXPORT(UToUpper);
	SYSEXPORT(UToLower);
}
////////////////////////////////////////////////////////////////////////////////
Warum klappt das Verlinken nicht. Was muss ich noch einstellen? Oder muss ich die C Datei anders übersetzen. Wenn ja, mit welchen Einstellungen. Ich gehe davon aus, dass ich wegen der geforderten Konpatibilität des .o Formates mit FPC zwingend GCC verwenden muss.

Es geht mir dabei weniger um Unicode, vielmehr geht es mir um die Vorgehensweise, um Code aus C/C++, der mir als .a, .lib, .o vorliegt, in Freepascal zu verwenden. Aktuell habe ich für meinen Test eine .o Datei als statische Bibliothek vorligen, deren Funktionen ich nutzen möchte.

Ist die Vorgehensweise bei .a und .lib Dateien die gleiche oder sind da wieder andere Dinge zu beachten und einzustellen. Habe das User Handbuch zu Freepascal durchgelesen. Dort ist aber leider nichts zum Format der Funktionsnamen gesagt auf die ich zugreifen will.

Wer kann mir weiter helfen?

Thandor
Beiträge: 153
Registriert: Sa 30. Jan 2010, 18:17
OS, Lazarus, FPC: Windows 10 64Bit/ lazarus 3.0 mit FPC 3.2.2 (32Bit + 64bit)
CPU-Target: 64Bit
Wohnort: Berlin

Re: name mangeling beim Linken von .o Dateien aus GCC?

Beitrag von Thandor »

eventuell hilft dir das:
http://wiki.freepascal.org/Cdecl/de

marcov
Beiträge: 1102
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: name mangeling beim Linken von .o Dateien aus GCC?

Beitrag von marcov »

Entweder Manuel entmanglede Name geben mit external name 'xxx', oder cdecl; nutzen (der das neben calling convention auch entmangelt und, teilwise, array of const anders definieert)

fpGUIcoder
Beiträge: 199
Registriert: Di 20. Okt 2015, 23:13

Re: name mangeling beim Linken von .o Dateien aus GCC?

Beitrag von fpGUIcoder »

@Thandor:

Danke für den Link. Hilft aber leider nicht weiter. Die C Quelltexte habe ich so vorliegen wie im Beispiel oben. Wenn ich nun die Direktive cdecl[]/b vor der external Direktive in meiner Pascal Unit ergänze erhalte ich diese Fehlermeldungen:

utext.pp(136,10) Error: Calling convention doesn't match forward
utext.pp(49,10) Error: Found declaration: UTextToUpper(AnsiString):AnsiString;
utext.pp(136,10) Error: function header doesn't match the previous declaration "UTextToUpper(AnsiString):AnsiString;"
utext.pp(49,10) Error: Found declaration: UTextToUpper(AnsiString):AnsiString;
utext.pp(146) Fatal: There were 4 errors compiling module, stopping
utext.pp(0) Fatal: Compilation aborted

@marcov:

Wie kann ich denn entmangelnde Namen vergeben?

Ich hatte angenommen, dass, wenn im C/C++ Quelltext keine Aufrufkonvention angegeben ist, wie im Beispiel oben, dass dann automatisch cdecl eingestellt ist. Scheint aber offenbar nicht so zu sein.

Was muss ich eventuell noch beachten, wenn ich mich dran mache, die C/C++ Quellen erneut zu übersetzen? Bisher habe ich die vorkompilierte .o Datei zu utext verwendet.

Wie kann ich das idiotensicher übersetzen und in Pascal dann idiotensicher verbinden. Welche Compilereinstellungen brauche ich da. Die .o Dateien sins statisch, keine dynamischen Bibliotheken.

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: name mangeling beim Linken von .o Dateien aus GCC?

Beitrag von Socke »

fpGUIcoder hat geschrieben:@Thandor:

Danke für den Link. Hilft aber leider nicht weiter. Die C Quelltexte habe ich so vorliegen wie im Beispiel oben. Wenn ich nun die Direktive cdecl[]/b vor der external Direktive in meiner Pascal Unit ergänze erhalte ich diese Fehlermeldungen:

utext.pp(136,10) Error: Calling convention doesn't match forward
utext.pp(49,10) Error: Found declaration: UTextToUpper(AnsiString):AnsiString;
utext.pp(136,10) Error: function header doesn't match the previous declaration "UTextToUpper(AnsiString):AnsiString;"
utext.pp(49,10) Error: Found declaration: UTextToUpper(AnsiString):AnsiString;
utext.pp(146) Fatal: There were 4 errors compiling module, stopping
utext.pp(0) Fatal: Compilation aborted

@marcov:

Wie kann ich denn entmangelnde Namen vergeben?

Ich hatte angenommen, dass, wenn im C/C++ Quelltext keine Aufrufkonvention angegeben ist, wie im Beispiel oben, dass dann automatisch cdecl eingestellt ist. Scheint aber offenbar nicht so zu sein.


Der Compiler beschwert sich hier ausschließlich über deinen Quelltext. Du hast zum einen eine Forward-Deklaration im Interface-Teil und zusätzlich die external-Deklaration im Implementation-Abschnitt. Du kannst die External-Informationen direkt im interface-Teil angeben; ansonsten musst du selbstverständlich alles bis auf "external name xyz" im Interface- und Implementation-Teil identisch halten.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

fpGUIcoder
Beiträge: 199
Registriert: Di 20. Okt 2015, 23:13

Re: name mangeling beim Linken von .o Dateien aus GCC?

Beitrag von fpGUIcoder »

@Socke:

Danke für den entscheidenden Hinweis. :)

Es beruhigt mich ungemein, dass ich wahrscheinlich NICHT anfangen muss, die C/C++ Quellen neu zu übersetzen, habe nämlich keinerlei Erfahrung mit dem GCC Compiler. :)

Ich habe jetzt die external Definitionen im Interface Teil. Wenn ich sie zusätzlich im Implementationsteil angebe, erhalte ich Meldung "Überladene Funktion hat selbe Parameterliste. Daher habe ich die Funktionköpfe aus dem Implementationsteil entfernt.

Nun aber erhalte ich die Compilermeldung:

Error: Undefined Symbol: _UTextToUpper.

Wenn ich aber den Unterstrich in meiner Deklaration vorne anfüge erhalte ich die gleiche Meldung, nur dann ist die Funktion ohne Unterstrich plötzlich undefiniert. Warum das?

So weit vom Ziel kann ich aber nun nicht mehr entfernt sein. Aber wie "überrede" ich nun den FPC Compiler zur Zusammenarbeit mit der C Funktion?

Hier nun noch, nach meiner Vermutung, beim Linken den Unterstrich vor meine Funktion zu setzen, bevor der Code zusammengesetzt wird?

Habe cdecl vorläufig nur bei der von mir auch aufgerufenen Funktion gesetzt. Für die anderen Funktionen will ich das nachholen, sobald diese eine Funktion korrekt mit FPC zusammenarbeitet.

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: name mangeling beim Linken von .o Dateien aus GCC?

Beitrag von Socke »

Kannst du nochmal deinen jetztigen Quelltext zeigen?
Am besten entfernst du hier dann alle Funktionen, die du zurzeit noch nicht brauchst (nur um die Übersicht zu behalten).
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

fpGUIcoder
Beiträge: 199
Registriert: Di 20. Okt 2015, 23:13

Re: name mangeling beim Linken von .o Dateien aus GCC?

Beitrag von fpGUIcoder »

Socke hat geschrieben:Kannst du nochmal deinen jetztigen Quelltext zeigen?
Am besten entfernst du hier dann alle Funktionen, die du zurzeit noch nicht brauchst (nur um die Übersicht zu behalten).
Ok, kann ich machen:

Zuerst die Pascal Unit:

Code: Alles auswählen

 
unit utext;
 
interface
 
uses Sysutils,cTypes;
 
{$LINK utext.o}
 
 
type
  l_utext = String;
 
function UTextToUpper( d: l_utext ): l_utext; cdecl external;
 
implementation
 
end.
 
Nun der zugehörige C-Quelltext:
--- hier nur meine Funktion, der vollständige C-Quelltext steht im ersten Beitrag oben. ---

Code: Alles auswählen

 
// Transform text to upper case
l_utext UTextToUpper( l_utext d ){
	l_utext l = d;
	if ( !DCkPt("UTextToUpper.d",d) ) return 0;
	while ( *d ){ *d = UToUpper(*d); d++; }
	return l;
}
 
Und so sieht die Export-Anweisung im C-Quelltext aus. Der enthält auch die Zeile:
#include dynld.h!
Aber seit wann werden .o Dateien dynamisch gelinkt?

Code: Alles auswählen

 
void InitUText ( void ) {
	SYSEXPORT(UTextToUpper);
}
 
Und hier mein Testprogramm:

Code: Alles auswählen

 
program test;
 
uses utext;
 
var
 testtext: l_utext;
 
begin
  testtext := 'mein testtext';
  writeln(testtext);
  writeln('Nun in Groábuchsteben umwandeln!');
  readln;
  testtext := UTextToUpper(testtext);
  writeln(testtext);
  write('Zurck mit << Enter >> ... ');
  readln;
end.
 

marcov
Beiträge: 1102
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: name mangeling beim Linken von .o Dateien aus GCC?

Beitrag von marcov »

fpGUIcoder hat geschrieben: @marcov:

Wie kann ich denn entmangelnde Namen vergeben?
Definition (definieren in Pascal, nutzen in C):

procedure xx; cdecl; [public,alias:'FPC_DOSYS1'];
begin
end;

Deklaration: (definieren in C, nutzen in pascal)

procedure xx; cdecl; external name 'FPC_DOSYS1';

oder

procedure xx; cdecl; external 'libraryname' name 'FPC_DOSYS1';

wenn es ein in ein DLL/Shared lib ist und das OS linkernamespaces hat (Windows und Kommerzielle Unixes wie Solaris und OS X. FreeBSD und Linux haben sie nicht)
Ich hatte angenommen, dass, wenn im C/C++ Quelltext keine Aufrufkonvention angegeben ist, wie im Beispiel oben, dass dann automatisch cdecl eingestellt ist. Scheint aber offenbar nicht so zu sein.
Es kann vielleicht wie bei Pascal sammt lokal (mit cdecl) und Global (mit ein Pragma) getan werden. Aber FPC ist standard NICHT cdecl, aber register, so etwas muss man da immer etwas tun. Deshalb ist der ersten Post falsch. Die externe Routinen sind nicht mit cdecl markiert.
Was muss ich eventuell noch beachten, wenn ich mich dran mache, die C/C++ Quellen erneut zu übersetzen? Bisher habe ich die vorkompilierte .o Datei zu utext verwendet.
Das C und C++ nicht dasselbe sein. Mit C möchte es funktionieren, aber C++ benötigt typisch Deklaration innerhalb ein extern C{ } Block.

Wie kann ich das idiotensicher übersetzen und in Pascal dann idiotensicher verbinden. Welche Compilereinstellungen brauche ich da. Die .o Dateien sins statisch, keine dynamischen Bibliotheken.[/quote]
  • cdecl ist standard fuer C/C++ aber vielleicht können Header den Standardwert aendern ueber Pragma.
  • C++ mangelt Funktionen default, C nicht.
  • C++ mangelt innerhalb ein extern C{} Block nicht
  • Delphi/FPC nutzen default "register" als Calling convention
  • (siehe Socke), FPC mag alles im interface und Implementation gleich deklariert. Eben mehr so wie Delphi.
  • automatisierte Typen wie Strings und Dynamische Arrays funktionieren fast nie in eine mehrsprachige Schnittstelle. Siehe auch http://stackoverflow.com/questions/1932 ... 16#1932916

fpGUIcoder
Beiträge: 199
Registriert: Di 20. Okt 2015, 23:13

Re: name mangeling beim Linken von .o Dateien aus GCC?

Beitrag von fpGUIcoder »

marcov hat geschrieben:
fpGUIcoder hat geschrieben: @marcov:

Wie kann ich denn entmangelnde Namen vergeben?
Definition (definieren in Pascal, nutzen in C):

procedure xx; cdecl; [public,alias:'FPC_DOSYS1'];
begin
end;

Deklaration: (definieren in C, nutzen in pascal)

procedure xx; cdecl; external name 'FPC_DOSYS1';

oder

procedure xx; cdecl; external 'libraryname' name 'FPC_DOSYS1';

wenn es ein in ein DLL/Shared lib ist und das OS linkernamespaces hat (Windows und Kommerzielle Unixes wie Solaris und OS X. FreeBSD und Linux haben sie nicht)
Ich hatte angenommen, dass, wenn im C/C++ Quelltext keine Aufrufkonvention angegeben ist, wie im Beispiel oben, dass dann automatisch cdecl eingestellt ist. Scheint aber offenbar nicht so zu sein.
Es kann vielleicht wie bei Pascal sammt lokal (mit cdecl) und Global (mit ein Pragma) getan werden. Aber FPC ist standard NICHT cdecl, aber register, so etwas muss man da immer etwas tun. Deshalb ist der ersten Post falsch. Die externe Routinen sind nicht mit cdecl markiert.
Was muss ich eventuell noch beachten, wenn ich mich dran mache, die C/C++ Quellen erneut zu übersetzen? Bisher habe ich die vorkompilierte .o Datei zu utext verwendet.
Das C und C++ nicht dasselbe sein. Mit C möchte es funktionieren, aber C++ benötigt typisch Deklaration innerhalb ein extern C{ } Block.

Wie kann ich das idiotensicher übersetzen und in Pascal dann idiotensicher verbinden. Welche Compilereinstellungen brauche ich da. Die .o Dateien sins statisch, keine dynamischen Bibliotheken.
  • cdecl ist standard fuer C/C++ aber vielleicht können Header den Standardwert aendern ueber Pragma.
  • C++ mangelt Funktionen default, C nicht.
  • C++ mangelt innerhalb ein extern C{} Block nicht
  • Delphi/FPC nutzen default "register" als Calling convention
  • (siehe Socke), FPC mag alles im interface und Implementation gleich deklariert. Eben mehr so wie Delphi.
  • automatisierte Typen wie Strings und Dynamische Arrays funktionieren fast nie in eine mehrsprachige Schnittstelle. Siehe auch http://stackoverflow.com/questions/1932 ... 16#1932916
[/quote]


Kann mal bitte jemand ein praktisches Beispiel bringen? Ichkann mir das so abstrakt leider nicht vorstellen.

Muss ich die eckigen Klammern setzen, wie oben in der Quellcodezeile?

Wie funktioniert das mit dem Alias?

Ich bekomme da Felermeldung "alias im Interfaceteil nicht erlaubt". "Oder alias und external vertragen sich nicht".

Gibt es also gar keine Möglichkeit, C/C++ Code zu linken. Im vorligenden Fall hab ich nur die Funktionen. Daher glaube ich, dass es sich dabei um C code handelt. Nach meinem Verständnis ist C++ die Erweiterung um die Klassen. Solche aber kommen hier nicht vor.

Wie kann ich den Code aus der .o Datei, deren Quellcode also in C vorliegt mit Pascal linken.

Ich brauche leider ein konkretes Beispiel!

fpGUIcoder
Beiträge: 199
Registriert: Di 20. Okt 2015, 23:13

Re: name mangeling beim Linken von .o Dateien aus GCC?

Beitrag von fpGUIcoder »

marcov hat geschrieben:
fpGUIcoder hat geschrieben: @marcov:

Wie kann ich denn entmangelnde Namen vergeben?
Definition (definieren in Pascal, nutzen in C):

procedure xx; cdecl; [public,alias:'FPC_DOSYS1'];
begin
end;

Deklaration: (definieren in C, nutzen in pascal)

procedure xx; cdecl; external name 'FPC_DOSYS1';

oder

procedure xx; cdecl; external 'libraryname' name 'FPC_DOSYS1';

wenn es ein in ein DLL/Shared lib ist und das OS linkernamespaces hat (Windows und Kommerzielle Unixes wie Solaris und OS X. FreeBSD und Linux haben sie nicht)
Ich hatte angenommen, dass, wenn im C/C++ Quelltext keine Aufrufkonvention angegeben ist, wie im Beispiel oben, dass dann automatisch cdecl eingestellt ist. Scheint aber offenbar nicht so zu sein.
Es kann vielleicht wie bei Pascal sammt lokal (mit cdecl) und Global (mit ein Pragma) getan werden. Aber FPC ist standard NICHT cdecl, aber register, so etwas muss man da immer etwas tun. Deshalb ist der ersten Post falsch. Die externe Routinen sind nicht mit cdecl markiert.
Was muss ich eventuell noch beachten, wenn ich mich dran mache, die C/C++ Quellen erneut zu übersetzen? Bisher habe ich die vorkompilierte .o Datei zu utext verwendet.
Das C und C++ nicht dasselbe sein. Mit C möchte es funktionieren, aber C++ benötigt typisch Deklaration innerhalb ein extern C{ } Block.

Wie kann ich das idiotensicher übersetzen und in Pascal dann idiotensicher verbinden. Welche Compilereinstellungen brauche ich da. Die .o Dateien sins statisch, keine dynamischen Bibliotheken.
  • cdecl ist standard fuer C/C++ aber vielleicht können Header den Standardwert aendern ueber Pragma.
  • C++ mangelt Funktionen default, C nicht.
  • C++ mangelt innerhalb ein extern C{} Block nicht
  • Delphi/FPC nutzen default "register" als Calling convention
  • (siehe Socke), FPC mag alles im interface und Implementation gleich deklariert. Eben mehr so wie Delphi.
  • automatisierte Typen wie Strings und Dynamische Arrays funktionieren fast nie in eine mehrsprachige Schnittstelle. Siehe auch http://stackoverflow.com/questions/1932 ... 16#1932916
[/quote]


Kann mal bitte jemand ein praktisches Beispiel bringen? Ichkann mir das so abstrakt leider nicht vorstellen.

Muss ich die eckigen Klammern setzen, wie oben in der Quellcodezeile?

Wie funktioniert das mit dem Alias?

Ich bekomme da Felermeldung "alias im Interfaceteil nicht erlaubt". "Oder alias und external vertragen sich nicht".

Gibt es also gar keine Möglichkeit, C/C++ Code zu linken. Im vorligenden Fall hab ich nur die Funktionen. Daher glaube ich, dass es sich dabei um C code handelt. Nach meinem Verständnis ist C++ die Erweiterung um die Klassen. Solche aber kommen hier nicht vor.

Wie kann ich den Code aus der .o Datei, deren Quellcode also in C vorliegt mit Pascal linken.

Ich brauche leider ein konkretes Beispiel!

Ich will von Freepascal auch die C Funktion(en) aufrufen. Wie bekomme ich das hin? Der Name in der C Datei hat den Unterstrich davor. Wie sage ich das dem FPC Compiler?

Hab das noch nie gemacht, dewegen frage ich vielleicht blöd. Sorry dfür, aber es muss doch da eine Möglichkeit geben!

laut GPL darf ich doch statisch linken?

.

marcov
Beiträge: 1102
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: name mangeling beim Linken von .o Dateien aus GCC?

Beitrag von marcov »

Ich habe leider keine mingw installation um so etwas vor zu bereiten.

Anonymus
Beiträge: 31
Registriert: Di 15. Dez 2015, 10:36

Re: name mangeling beim Linken von .o Dateien aus GCC?

Beitrag von Anonymus »

Also wenn ich mir den Thread so anschaue, scheint es schneller per Hand zu gehen. Alle C/C++ Dateien nach Pascal konvertieren und gut is. Ein Bekannter von mir hatte so ein Problem mit Delphi und Visual C++.

Der hat dann entnervt aufgegeben und die C/C++ Dateien, die er brauchte in Pascal übersetzt und fertig.

marcov
Beiträge: 1102
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: name mangeling beim Linken von .o Dateien aus GCC?

Beitrag von marcov »

Anonymus hat geschrieben:Also wenn ich mir den Thread so anschaue, scheint es schneller per Hand zu gehen. Alle C/C++ Dateien nach Pascal konvertieren und gut is. Ein Bekannter von mir hatte so ein Problem mit Delphi und Visual C++.

Der hat dann entnervt aufgegeben und die C/C++ Dateien, die er brauchte in Pascal übersetzt und fertig.
Ah, aber Delphi und Visual C++ nutzen ein anderes Objekt format. Mingw und FPC sind da kompatibel. Man muss sich nur ein bisschen anstrengen.

Anonymus
Beiträge: 31
Registriert: Di 15. Dez 2015, 10:36

Re: name mangeling beim Linken von .o Dateien aus GCC?

Beitrag von Anonymus »

@Markov:

Dass sich @fpGUIcoder nur nicht genug anstrengt, kann ich nicht erkennen. Wenn die genannten codes nicht weiter helfen scheint es mit der Kompatibilität doch nicht so weit her zu sein.

Soweit ich mich mit freepascal auskenne, geht die alias Direktive nicht im Interfaceteil. Und die External Definitionen der Pascal Funktionen befinden sich im Interfaceteil.

Wenn ich mir dann noch das Problem mit dem Underscore anschaue und er schon alles mögliche, womöglich noch andere Direktiven getestet hat und nicht weiter kommt, das kann er sich wohl "anstrengen" wie er will, aber nicht zum Ziel kommen.
So ein programmiersprachenübergreifendes Problem hatte auch ich schon mal. Ich hatte mich damals für das Umschreiben des Codes entschieden.

Da kann er sich nur noch in 2 Richtungen "anstrengen":

a) den C Code neu übersetzen.
---- geht nur bei sicherem Beherrschen des Compilers, sonst ist eine Schritt für Schritt Konvertierung nach FPC schneller. Ich kann
---- mich noch sehr gut an meine Anfängerzeit erinnern. Ein Kreuz ist das mit den Make Dateien und Kommandozeilentools. Wer
---- da nicht wirklich fit ist mit den Tools, ....

b) den C Code gleich nach Pascal konvertieren.
---- dann entfällt die Link Problematik für nachfolgende Nutzer der Bibliothek. Und es entfällt die Einarbeitung in den GCC.

Diese Nachfolger könnten genauso neu sein wie @fpGUIcoder und dann auch Copmpilereinstellungen vergessen und das Übersetzen funktioniert dann auch nicht. Und wenn sich de rUser in den GCC Compiler erst mal einarbeiten muss, wird wohl auch die Schritt für Schritt Konvertierung schneller sein. Habe interessehalber paar Dokus zu den Compilern angelesen. Eh man da alles wirklich beherrscht, vergeht viel Zeit. Und so oft kommt so eine Konvertierung nun auch nicht vor. Wenn der User keine Erfahrung mit GCC hat, dann rate ich zur Schritt für Schritt Konvertierung. Hätte er mit C Erfahrung, würde er die Bibliothek in C verwenden und sich den Stress hier sparen. Würd ich jedenfalls so machen.

Hausaufgabenthreads sehen anders aus. Dies hier sieht nicht nach einer solchen aus.

Außerdem ist es ein Unterschied, ob er statisch oder dynamisch linken will. Ich glaub, irgendwo im Strang gelesen zu haben, dass er .o Dateien linken will. Da tipp ich mal auf statisches Linken. Dynamisch macht da keinen Sinn. Er will halt allen Code in EINER .exe haben. Hat durchaus Vorteile. SO muss er keine .dll Dateien mitgeben oder installieren.

Antworten