DLL Returning char *

Discussion in 'C++' started by Joey Sabey, Jan 18, 2007.

  1. Joey Sabey

    Joey Sabey Guest

    Hey, I've got a bit of a strange problem caused by a situation I'm in.
    I'm writing a DLL for a friend of mine in C++, and he plans to use it
    in delphi. The DLL needs to return strings, and we doubt that a string
    would return well to a delphi program, so the only thing I could think
    of was returning a char*, which obviously would be very dangerous as
    the array would be being declared as a local variable and would only be
    returning it's address.
    Anyway, anyone know a solution to such a problem? I can't think of
    anything myself, as I'm not that an experienced C++ programmer as it
    is, and the whole delphi aspect complicates things for me, as I know
    nothing of it.
     
    Joey Sabey, Jan 18, 2007
    #1
    1. Advertising

  2. Joey Sabey

    Ondra Holub Guest

    Joey Sabey napsal:
    > Hey, I've got a bit of a strange problem caused by a situation I'm in.
    > I'm writing a DLL for a friend of mine in C++, and he plans to use it
    > in delphi. The DLL needs to return strings, and we doubt that a string
    > would return well to a delphi program, so the only thing I could think
    > of was returning a char*, which obviously would be very dangerous as
    > the array would be being declared as a local variable and would only be
    > returning it's address.
    > Anyway, anyone know a solution to such a problem? I can't think of
    > anything myself, as I'm not that an experienced C++ programmer as it
    > is, and the whole delphi aspect complicates things for me, as I know
    > nothing of it.


    Hi. I think it is question more related to some delphi forum. If you
    are using only C interface for your shared library, it should be
    accessible by other languages. Most modern languages have some
    capability to call routines written in C/C++.
     
    Ondra Holub, Jan 18, 2007
    #2
    1. Advertising

  3. Joey Sabey

    Joey Sabey Guest

    Ondra Holub wrote:

    > Hi. I think it is question more related to some delphi forum. If you
    > are using only C interface for your shared library, it should be
    > accessible by other languages. Most modern languages have some
    > capability to call routines written in C/C++.


    Well, it might be more suited there, but I doubt it, as I am writing
    the thing in C++, and they would likely not be able to help... I might
    try looking for a delphi place to ask though...
     
    Joey Sabey, Jan 18, 2007
    #3
  4. Joey Sabey

    Ondra Holub Guest

    Joey Sabey napsal:
    > Ondra Holub wrote:
    >
    > > Hi. I think it is question more related to some delphi forum. If you
    > > are using only C interface for your shared library, it should be
    > > accessible by other languages. Most modern languages have some
    > > capability to call routines written in C/C++.

    >
    > Well, it might be more suited there, but I doubt it, as I am writing
    > the thing in C++, and they would likely not be able to help... I might
    > try looking for a delphi place to ask though...


    I tried to search for it with google and have found this:

    http://www.rvelthuis.de/articles/articles-cppobjs.html
     
    Ondra Holub, Jan 18, 2007
    #4
  5. Joey Sabey

    Joey Sabey Guest

    Ondra Holub wrote:

    > Joey Sabey napsal:
    > > Ondra Holub wrote:
    > >
    > > > Hi. I think it is question more related to some delphi forum. If you
    > > > are using only C interface for your shared library, it should be
    > > > accessible by other languages. Most modern languages have some
    > > > capability to call routines written in C/C++.

    > >
    > > Well, it might be more suited there, but I doubt it, as I am writing
    > > the thing in C++, and they would likely not be able to help... I might
    > > try looking for a delphi place to ask though...

    >
    > I tried to search for it with google and have found this:
    >
    > http://www.rvelthuis.de/articles/articles-cppobjs.html


    Thanks.
    I don't really get that, though... Theres a lot of delphi and stuff...
    And, if the class functions are accessed as functions, what happens to
    the class variables? =/ It's pretty confusing...
     
    Joey Sabey, Jan 18, 2007
    #5
  6. Joey Sabey

    Dennis Jones Guest

    "Joey Sabey" <> wrote in message
    news:...
    >
    > Ondra Holub wrote:
    >
    >> Hi. I think it is question more related to some delphi forum. If you
    >> are using only C interface for your shared library, it should be
    >> accessible by other languages. Most modern languages have some
    >> capability to call routines written in C/C++.

    >
    > Well, it might be more suited there, but I doubt it, as I am writing
    > the thing in C++, and they would likely not be able to help... I might
    > try looking for a delphi place to ask though...


    In the future, a good bet for getting answers that relate to both Delphi AND
    C++ is to ask in one of the C++Builder forums since most C++Builder
    developers are also generally knowledgeable in Delphi.

    To answer your question, Delphi has a "pchar" (pointer to string) type which
    is the equivelent of a "char *" in C/C++. But, as you have surmised, you
    should not return a char * as a reference a local string in the DLL back to
    the EXE, but this would be true no matter what lanaguage the executable was
    written in (not just Delphi). For any function that needs to return a char
    *, you should have it accept two arguments: a char *, to which you would
    copy the string, and a size parameter that specifies how big the buffer is:

    void SomeFunc( char * str, int size )
    {
    strncpy( str, "some text", size-1 ); // don't write past the end of the
    given buffer!
    str[size-1] = '\0'; // make sure the string is null-terminated!
    }

    The Delphi program would then call this function passing a 'pchar' (pointer
    to some buffer) and a buffer size argument. The Delphi program would own
    the memory to the buffer, so you don't have to worry about memory
    allocations going across the DLL/EXE boundary.

    Then of course, you have to make sure the function is exported by the DLL
    and usable by Delphi. To do this, the function must use the standard
    calling convention, and must be declared as exportable:

    extern __declspec( dllexport ) void __stdcall SomeFunc( char * str, int
    size );

    To use this function, the Delphi program must define an equivelent prototype
    and import the function from the DLL:

    SomeFunc : procedure( str : pchar; size : integer ); stdcall;

    SomeFunc := GetProcAddress(GetModuleHandle('yourdll.dll'), 'SomeFunc');

    I am a C++Builder developer (but by no means a Delphi expert) and none of
    the code above has been tested, but it should provide you with enough
    information to get you started.

    - Dennis
     
    Dennis Jones, Jan 18, 2007
    #6
  7. Joey Sabey

    Joey Sabey Guest

    Dennis Jones wrote:
    >For any function that needs to return a char
    > *, you should have it accept two arguments: a char *, to which you would
    > copy the string, and a size parameter that specifies how big the buffer is:


    Problem is that the EXE doesn't know how big the data back is gonna be,
    it could be small, or a lot bigger, meaning you'd have to pass a very
    large, and inefficient, buffer... I doubt that'd would help at all.

    Would packing the data into a struct or something help at all..?
     
    Joey Sabey, Jan 18, 2007
    #7
  8. Joey Sabey

    Dennis Jones Guest

    "Joey Sabey" <> wrote in message
    news:...
    >
    > Dennis Jones wrote:
    >>For any function that needs to return a char
    >> *, you should have it accept two arguments: a char *, to which you would
    >> copy the string, and a size parameter that specifies how big the buffer
    >> is:

    >
    > Problem is that the EXE doesn't know how big the data back is gonna be,
    > it could be small, or a lot bigger, meaning you'd have to pass a very
    > large, and inefficient, buffer... I doubt that'd would help at all.
    >
    > Would packing the data into a struct or something help at all..?



    No, but you could do like some Windows API functions do and have the
    function return the size of the needed buffer. So something like this very
    simple example:

    int SomeFunc( char *str, int size )
    {
    char text[] = "some text";
    int reqsize = strlen( text ) + 1;

    if ( str != NULL && size >= reqsize )
    {
    strncpy( str, text, size-1 );
    str[size-1] = '\0';
    }
    return reqsize;
    }

    Now the caller can call SomeFunc() with either a null pointer or an
    insufficiently sized buffer and your function will return the necessary
    buffer size:

    int bufsize = 0;
    char *somebuffer = NULL;

    int reqsize = SomeFunc( NULL, 0 ); // how much space do we need?
    bufsize = reqsize;
    somebuffer = new char[bufsize]; // allocate it

    reqsize = SomeFunc( somebuffer, bufsize );
    if ( reqsize <= bufsize ) // somebuffer was both non-NULL and big enough
    to hold the data
    {
    // use somebuffer
    }

    - Dennis
     
    Dennis Jones, Jan 18, 2007
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Anushi
    Replies:
    5
    Views:
    8,807
  2. Anders Thomsen
    Replies:
    1
    Views:
    2,779
    Jeff Schwab
    Apr 30, 2004
  3. Replies:
    11
    Views:
    670
    Christos Georgiou
    May 2, 2006
  4. lovecreatesbeauty
    Replies:
    1
    Views:
    1,071
    Ian Collins
    May 9, 2006
  5. H. Simpson
    Replies:
    4
    Views:
    294
    H. Simpson
    Aug 3, 2004
Loading...

Share This Page