Board index » cppbuilder » Functions calling convention

Functions calling convention


2007-08-28 11:53:45 PM
cppbuilder99
Hi to all
I have a problema using a C-style DLL inside a C++ program. I have the dll
and to generate the lib fine I use the implib utility
I have the .h file, and the functions are like this:
extern "C"
{
DLL_EXPORT void functionName(int x);
}
in this declaration I asume tha the calling cinvention is __cdecl (C++)
I my program I include the ".h" fine an call the funcion, and when linking
there is a error that say the linker is unabled to find "_functionName"
To solve the problem in the program i change the calling convention to
__stdcall (no mangling), but when I call some function inside the DLL I get
an error EAccessViolation
Somebody can help me?
Tx a lot
jaimes
 
 

Re:Functions calling convention

jaimes wrote:
Quote
Somebody can help me?


The calling convention still can be cdecl, just without the underscore.
MSC compiler is known for doing that. Run implib on the DLL and use the
switches to generate Borland-compatible symbols. Or use .def file with
the IMPORTS section and type the name yourself.
.a
 

Re:Functions calling convention

Hi Alex
tx for your reply
I use a DLL viwer to view the functions inside the DLL, and the functios are
without underscore "_"
I´m trying using "dumpbin" from VC++, and the list of functions are without
the "_" symbol
My question is: if I use the .def file how I can use it in a program???
(I know how to use .lib files, but I never use .def files)
tx for your time
jaimes
"Alex Bakaev [TeamB]" < XXXX@XXXXX.COM >escribi?en el mensaje
Quote
jaimes wrote:

>Somebody can help me?
>
>

The calling convention still can be cdecl, just without the underscore.
MSC compiler is known for doing that. Run implib on the DLL and use the
switches to generate Borland-compatible symbols. Or use .def file with the
IMPORTS section and type the name yourself.
.a
 

{smallsort}

Re:Functions calling convention

"Alex Bakaev [TeamB]" < XXXX@XXXXX.COM >wrote in message
Quote
jaimes wrote:

>Somebody can help me?
>
>

The calling convention still can be cdecl, just without the underscore.
MSC compiler is known for doing that. Run implib on the DLL and use the
switches to generate Borland-compatible symbols. Or use .def file with the
IMPORTS section and type the name yourself.
.a
More specifically, try re-generating your import library with implib using
the "-a" switch, and see if that helps.
 

Re:Functions calling convention

I generate the .lib file using implib -a a.lib a.dll and I have the same
linker problem
"dhoke" < XXXX@XXXXX.COM >escribi?en el mensaje
Quote

"Alex Bakaev [TeamB]" < XXXX@XXXXX.COM >wrote in message
news:46d44c66$ XXXX@XXXXX.COM ...
>jaimes wrote:
>
>>Somebody can help me?
>>
>>
>
>The calling convention still can be cdecl, just without the underscore.
>MSC compiler is known for doing that. Run implib on the DLL and use the
>switches to generate Borland-compatible symbols. Or use .def file with
>the IMPORTS section and type the name yourself.
>.a

More specifically, try re-generating your import library with implib using
the "-a" switch, and see if that helps.

 

Re:Functions calling convention

I found the solution
www.fftw.org/install/bcb-fftw3.html
Now I have anothe problem, in the DLL I have one struct
struct XX
{
char* text;
}
void someFunctionInit(XX* x)
{
x.text = NULL;
}
void someFunction(XX* x)
{
if( x.text )
{
printf("%s",x->text);
}
}
in the client code I have:
XX x = new XX();
someFunctionInit( x);
x->text = strdup( "something" );
someFunction( x );
but when the program is running x->text still have a NULL value inside
someFunction, some idea??
tx for your time
jaimes
"jaimes" < XXXX@XXXXX.COM >escribi?en el mensaje
Quote
Hi to all

I have a problema using a C-style DLL inside a C++ program. I have the dll
and to generate the lib fine I use the implib utility

I have the .h file, and the functions are like this:

extern "C"
{
DLL_EXPORT void functionName(int x);
}

in this declaration I asume tha the calling cinvention is __cdecl (C++)

I my program I include the ".h" fine an call the funcion, and when linking
there is a error that say the linker is unabled to find "_functionName"

To solve the problem in the program i change the calling convention to
__stdcall (no mangling), but when I call some function inside the DLL I
get an error EAccessViolation

Somebody can help me?

Tx a lot

jaimes



 

Re:Functions calling convention

"jaimes" < XXXX@XXXXX.COM >wrote in message
Quote
Now I have anothe problem, in the DLL I have one struct

struct XX
{
char* text;
}

void someFunctionInit(XX* x)
{
x.text = NULL;
}
void someFunction(XX* x)
{
if( x.text )
{
printf("%s",x->text);
}
}


in the client code I have:

XX x = new XX();

someFunctionInit( x);
x->text = strdup( "something" );
someFunction( x );

but when the program is running x->text still have a NULL value inside
someFunction, some idea??
None of the code you show here should even compile! Therefore, one can only
assume that it is not your actual code. Please show the *actual* code.
- Dennis
 

Re:Functions calling convention

Ok, here is the actual code
DLL code
-----------------------------------------------------------------------------
mapObj *msNewMapObj()
{
mapObj *map;
/* create an empty map, no layers etc... */
map = (mapObj *)calloc(sizeof(mapObj),1);
if(!map)
{
msSetError(MS_MEMERR, NULL, "msCreateMap()");
return NULL;
}
if( initMap( map ) == -1 )
return NULL;
if( msPostMapParseOutputFormatSetup( map ) == MS_FAILURE )
return NULL;
return map;
}
************************ the initMap function set the map->shapepath to NULL
************************ msSaveMap test if map->shapepath!=NULL
int msSaveMap(mapObj *map, char *filename)
{
int i;
FILE *stream;
char szPath[MS_MAXPATHLEN];
const char *key;
if(!map) {
msSetError(MS_MISCERR, "Map is undefined.", "msSaveMap()");
return(-1);
}
if(!filename) {
msSetError(MS_MISCERR, "Filename is undefined.", "msSaveMap()");
return(-1);
}
stream = fopen(msBuildPath(szPath, map->mappath, filename), "w");
if(!stream) {
msSetError(MS_IOERR, "(%s)", "msSaveMap()", filename);
return(-1);
}
fprintf(stream, "MAP\n");
if(map->datapattern) fprintf(stream, " DATAPATTERN \"%s\"\n",
map->datapattern);
fprintf(stream, " EXTENT %.15g %.15g %.15g %.15g\n", map->extent.minx,
map->extent.miny, map->extent.maxx, map->extent.maxy);
if(map->fontset.filename) fprintf(stream, " FONTSET \"%s\"\n",
map->fontset.filename);
if(map->templatepattern) fprintf(stream, " TEMPLATEPATTERN \"%s\"\n",
map->templatepattern);
fprintf(stream, " IMAGECOLOR %d %d %d\n", map->imagecolor.red,
map->imagecolor.green, map->imagecolor.blue);
if( map->imagetype != NULL )
fprintf(stream, " IMAGETYPE %s\n", map->imagetype );
if(map->resolution != 72.0) fprintf(stream, " RESOLUTION %f\n",
map->resolution);
if(map->interlace != MS_NOOVERRIDE)
fprintf(stream, " INTERLACE %s\n", msTrueFalse[map->interlace]);
if(map->symbolset.filename) fprintf(stream, " SYMBOLSET \"%s\"\n",
map->symbolset.filename);
if(map->shapepath) fprintf(stream, " SHAPEPATH \"%s\"\n", map->shapepath);
fprintf(stream, " SIZE %d %d\n", map->width, map->height);
if(map->maxsize != MS_MAXIMAGESIZE_DEFAULT) fprintf(stream, " MAXSIZE
%d\n", map->maxsize);
fprintf(stream, " STATUS %s\n", msStatus[map->status]);
if( map->transparent != MS_NOOVERRIDE )
fprintf(stream, " TRANSPARENT %s\n", msTrueFalse[map->transparent]);
fprintf(stream, " UNITS %s\n", msUnits[map->units]);
for( key = msFirstKeyFromHashTable( &(map->configoptions) );
key != NULL;
key = msNextKeyFromHashTable( &(map->configoptions), key ) )
{
fprintf( stream, " CONFIG %s \"%s\"\n",
key, msLookupHashTable( &(map->configoptions), key ) );
}
fprintf(stream, " NAME \"%s\"\n\n", map->name);
if(map->debug) fprintf(stream, " DEBUG ON\n");
writeOutputformat(map, stream);
/* write symbol with INLINE tag in mapfile */
for(i=0; i<map->symbolset.numsymbols; i++)
{
writeSymbol(&(map->symbolset.symbol[i]), stream);
}
writeProjection(&(map->projection), stream, " ");
writeLegend(&(map->legend), stream);
writeQueryMap(&(map->querymap), stream);
writeReferenceMap(&(map->reference), stream);
writeScalebar(&(map->scalebar), stream);
writeWeb(&(map->web), stream);
for(i=0; i<map->numlayers; i++)
{
writeLayer(&(map->layers[map->layerorder[i]]), stream);
/* writeLayer(&(map->layers[i]), stream); */
}
fprintf(stream, "END\n");
fclose(stream);
return(0);
}
Client code
-----------------------------------------------------------------------------
int main(int argc, char* argv[])
{
mapObj* map = msNewMapObj( );
msMapSetExtent( map,0,1,10,20000 );
msMapSetSize( map,50,60 );
map->shapepath = strdup("xx");
map->status = MS_ON;
map->imagetype = "JPG";
msSaveMap( map,"c:/11/a.map");
msFreeMap( map );
printf("terminado...");
return 0;
}
after that code, there is a file called c:/11/a.map thet must contains the
text
...
SHAPEPATH xx
"Dennis Jones" < XXXX@XXXXX.COM >escribi?en el mensaje
Quote

"jaimes" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>Now I have anothe problem, in the DLL I have one struct
>
>struct XX
>{
>char* text;
>}
>
>void someFunctionInit(XX* x)
>{
>x.text = NULL;
>}
>void someFunction(XX* x)
>{
>if( x.text )
>{
>printf("%s",x->text);
>}
>}
>
>
>in the client code I have:
>
>XX x = new XX();
>
>someFunctionInit( x);
>x->text = strdup( "something" );
>someFunction( x );
>
>but when the program is running x->text still have a NULL value inside
>someFunction, some idea??

None of the code you show here should even compile! Therefore, one can
only assume that it is not your actual code. Please show the *actual*
code.

- Dennis

 

Re:Functions calling convention

"jaimes" < XXXX@XXXXX.COM >wrote in message
Quote
Ok, here is the actual code


DLL code
-----------------------------------------------------------------------------
mapObj *msNewMapObj()
Where's the definition of mapObj?
- Dennis
 

Re:Functions calling convention

typedef struct map_obj{ /* structure for a map */
char *name; /* small identifier for naming etc. */
int status; /* is map creation on or off */
int height, width;
int maxsize;
#ifndef SWIG
layerObj *layers;
#endif /* SWIG */
#ifdef SWIG
%immutable;
#endif /* SWIG */
int numlayers; /* number of layers in mapfile */
symbolSetObj symbolset;
fontSetObj fontset;
labelCacheObj labelcache; /* we need this here so multiple feature
processors can access it */
#ifdef SWIG
%mutable;
#endif /* SWIG */
int transparent; /* TODO - Deprecated */
int interlace; /* TODO - Deprecated */
int imagequality; /* TODO - Deprecated */
rectObj extent; /* map extent array */
double cellsize; /* in map units */
#ifndef SWIG
geotransformObj gt; /* rotation / geotransform */
#endif /*SWIG*/
rectObj saved_extent;
enum MS_UNITS units; /* units of the projection */
double scale; /* scale of the output image */
double resolution;
char *shapepath; /* where are the shape files located */
char *mappath; /* path of the mapfile, all path are relative to this path
*/
#ifndef SWIG
paletteObj palette; /* holds a map palette */
#endif /*SWIG*/
colorObj imagecolor; /* holds the initial image color value */
#ifdef SWIG
%immutable;
#endif /* SWIG */
int numoutputformats;
outputFormatObj **outputformatlist;
outputFormatObj *outputformat;
char *imagetype; /* name of current outputformat */
#ifdef SWIG
%mutable;
#endif /* SWIG */
#ifndef SWIG
projectionObj projection; /* projection information for output map */
projectionObj latlon; /* geographic projection definition */
#endif /* not SWIG */
#ifdef SWIG
%immutable;
#endif /* SWIG */
referenceMapObj reference;
scalebarObj scalebar;
legendObj legend;
queryMapObj querymap;
webObj web;
#ifdef SWIG
%mutable;
#endif /* SWIG */
int *layerorder;
int debug;
char *datapattern, *templatepattern;
#ifdef SWIG
%immutable;
#endif /* SWIG */
hashTableObj configoptions;
#ifdef SWIG
%mutable;
#endif /* SWIG */
#ifndef SWIG
/* Private encryption key information - see mapcrypto.c */
int encryption_key_loaded; /* MS_TRUE once key has been loaded */
unsigned char encryption_key[MS_ENCRYPTION_KEY_SIZE]; /* 128bits
encryption key */
#endif
} mapObj;
jaimes
"Dennis Jones" < XXXX@XXXXX.COM >escribi?en el mensaje
Quote

"jaimes" < XXXX@XXXXX.COM >wrote in message
news:46d475d3$ XXXX@XXXXX.COM ...
>Ok, here is the actual code
>
>
>DLL code
>-----------------------------------------------------------------------------
>mapObj *msNewMapObj()

Where's the definition of mapObj?

- Dennis

 

Re:Functions calling convention

jaimes wrote:
Quote
mapObj *msNewMapObj()
{
mapObj *map;
map = (mapObj *)calloc(sizeof(mapObj),1);
if( initMap( map ) == -1 )
Memory leak of map
Quote
return NULL;
if( msPostMapParseOutputFormatSetup( map ) == MS_FAILURE )
Memory leak of map
Quote
return NULL;
return map;
}
int msSaveMap(mapObj *map, char *filename)
{
if(map->shapepath) fprintf(stream, " SHAPEPATH \"%s\"\n", map->shapepath);
-----------------------------------------------------------------------------
int main(int argc, char* argv[])
{
mapObj* map = msNewMapObj( );
map->shapepath = strdup("xx");
<Help>
strdup returns a pointer to the storage location containing the
duplicated string, or returns null if space could not be allocated.
</Help>
Try it this way and see what happens
char spath[] = "xx";
map->shapepath = spath;
Note that this only works in main
(or within a single routine that owns the map.)
If it was done in a subroutine, the pointer would
be invalid after the routine returned.
Quote
msSaveMap( map,"c:/11/a.map");
after that code, there is a file called c:/11/a.map thet must contains the
text
SHAPEPATH xx
 

Re:Functions calling convention

Hi, tx for your answer
I was trying all the posible solutions and simply dont work!
I check if strdup return null, I use new operator, malloc, and nothing work
the problem is that the memory that I assign to "shapepath" in the program,
the server see as a NULL value. I´m trying with others variables like
"shapepath" (like imagetype) and don´t work (the problem is with all
variables of type char *), others types like int work fine
is there a problem with the memory manager beetwen a C-styled DLL (compiled
in VC++) and a C++ program made with BCB?
tx
jaimes
"Bob Gonder" < XXXX@XXXXX.COM >escribi?en el mensaje
Quote
jaimes wrote:

>mapObj *msNewMapObj()
>{
>mapObj *map;
>map = (mapObj *)calloc(sizeof(mapObj),1);
>if( initMap( map ) == -1 )

Memory leak of map

>return NULL;
>if( msPostMapParseOutputFormatSetup( map ) == MS_FAILURE )

Memory leak of map

>return NULL;
>return map;
>}

>int msSaveMap(mapObj *map, char *filename)
>{
>if(map->shapepath) fprintf(stream, " SHAPEPATH \"%s\"\n",
>map->shapepath);

>-----------------------------------------------------------------------------
>int main(int argc, char* argv[])
>{
>mapObj* map = msNewMapObj( );

>map->shapepath = strdup("xx");

<Help>
strdup returns a pointer to the storage location containing the
duplicated string, or returns null if space could not be allocated.
</Help>
Try it this way and see what happens
char spath[] = "xx";
map->shapepath = spath;

Note that this only works in main
(or within a single routine that owns the map.)
If it was done in a subroutine, the pointer would
be invalid after the routine returned.

>msSaveMap( map,"c:/11/a.map");

>after that code, there is a file called c:/11/a.map thet must contains the
>text
>SHAPEPATH xx


 

Re:Functions calling convention

"jaimes" < XXXX@XXXXX.COM >writes:
Quote
is there a problem with the memory manager beetwen a C-styled DLL (compiled
in VC++) and a C++ program made with BCB?
That depends what you mean by your question. You absolutely cannot,
for example, allocate memory in the dll and deallocate it in the
executable. And vice versa.
If the dll allocates, the dll must deallocate. That may require your
dll to provide allocate and deallocation routines, even if they just
call new/delete or malloc/free. The important thing is that the
new/delete are done in code compiled by the same compiler, with the
same memory allocator in use by both.
Not sure if that's your problem or not, but it seems worth
mentioning.
--
Chris (TeamB);
 

Re:Functions calling convention

"Chris Uzdavinis (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote
"jaimes" < XXXX@XXXXX.COM >writes:

>is there a problem with the memory manager beetwen a C-styled DLL
>(compiled
>in VC++) and a C++ program made with BCB?


Not sure if that's your problem or not, but it seems worth
mentioning.
His DLL code has allocation/deallocation routines that are being called from
the app, so that's not his problem.
- Dennis
 

Re:Functions calling convention

jaimes wrote:
Quote
the problem is that the memory that I assign to "shapepath" in the program,
the server see as a NULL value.
Then you are doing something else wrong.
In the de{*word*81}, Watch or Inspect "map", and step through the code,
watching map->shapepath at each step.
When it changes to NULL, you will find the culprit.