Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Dll function with STL obj. as parameter call crach

12 views
Skip to first unread message

Miasnik@discussions.microsoft.com Iliya Miasnik

unread,
Oct 12, 2009, 3:11:02 PM10/12/09
to

Hello.
The application call function (with STL string object as parameter) from dll.
If dll compiled in different mode (release/debug) than application we see
this crash.

We use Visual Studio 2008 (Windows Mobile 5.0 Pocket PC SDK (ARMV4I)

The foolowing code of application:
typedef int (*GETINIFILEIMPL)(const std::wstring& wstrIniFileName);
...
std::wstring someStr(L"trali vali");
GETINIFILEIMPL getImpl = NULL;
HMODULE hLib = LoadLibrary(L"SomeDLL.dll");

if(NULL == hLib)
return 0;

getImpl = (GETINIFILEIMPL)GetProcAddress(hLib, L"fnSomeDLL");
if(getImpl)
getImpl(someStr); // here we pass STL obj (by refefence)to dll

FreeLibrary(hLib);

The following function code of dll:

SOMEDLL_API int fnSomeDLL(const std::wstring& parStr)
{
RETAILMSG(1, (L"------ %s\r\n", parStr.c_str())); // crash !!!!
return 42;
}

Do you have this problem?
Do we write code in wrong way?

David Lowndes

unread,
Oct 12, 2009, 7:24:01 PM10/12/09
to

>The application call function (with STL string object as parameter) from dll.
>If dll compiled in different mode (release/debug) than application we see
>this crash.

Yes, that's to be expected. Expecting heap allocated objects to be
freed, manipulated, or re-allocated across module boundaries only
works if both components use the same (DLL) version of the run-time.
Otherwise they have different heaps - because the debug version has
additional features (to aid debugging) that the release version
doesn't have.

Dave

Ismo Salonen

unread,
Oct 13, 2009, 2:57:10 AM10/13/09
to

Also STL objects itself are different size in debug and release builds,
debug version have extra fields for detecting runaway iterators.

ismo

Giovanni Dicanio

unread,
Oct 13, 2009, 4:47:54 AM10/13/09
to

"Ismo Salonen" <Ismo.S...@codeit.fi> ha scritto nel messaggio
news:u7KVkJ9S...@TK2MSFTNGP04.phx.gbl...

> Also STL objects itself are different size in debug and release builds,
> debug version have extra fields for detecting runaway iterators.

And I think that also in debug builds the sizes can be different, if code is
compiled with different options like _HAS_ITERATOR_DEBUGGING enabled or
disabled.

So from some point of view, to safely use STL classes at DLL boundaries,
that should be treated as equivalent to static linking with respect to
compiler version, compiler options, etc.

My understanding is that the only robust way to export classes via DLLs (and
being independent from compiler version, compiler options, etc.) is using
COM.

Giovanni

Iliya Miasnik

unread,
Oct 15, 2009, 11:54:15 AM10/15/09
to

"David Lowndes" wrote:

We used STL objects the same way in our projects for Embeded Visual Studio
4.0 with Pocket PC SDK without this problems.
Something was changed in STL implementation?

David Lowndes

unread,
Oct 15, 2009, 1:19:11 PM10/15/09
to
>We used STL objects the same way in our projects for Embeded Visual Studio
>4.0 with Pocket PC SDK without this problems.
>Something was changed in STL implementation?

It's nothing really to do with the STL implementation, just the
underlying run-time library.

Dave

Stephen Howe

unread,
Oct 28, 2009, 4:29:18 PM10/28/09
to

>We used STL objects the same way in our projects for Embeded Visual Studio
>4.0 with Pocket PC SDK without this problems.
>Something was changed in STL implementation?

Nothing to do with STL.

If you are using static libraries

1. You can't fopen() a file in an EXE and then expect to fread(), fwrite(), fprintf(), fclose() with the same pointer in a DLL
2. You can't start strtok() in an EXE and then expect to continue strtok() in an DLL with the same pointer
3. You can't malloc()/calloc() some memory in an EXE and then expect to free() the same pointer in an DLL
4. You can't new some object in an EXE and then expect to delete the same object in an DLL
5. You can't new[] some objects in an EXE and then expect to delete [] the same objects in an DLL
6. You cant create a std::vector() in an EXE and then expect to resize it beyond the capacity in the DLL
etc...

In short you cannot expect the static state of C/C++ that is maintained in EXE and the DLL which has a _DIFFERENT maintained
static state of C/C++, to be magically aware of each other and compensate.
They are unaware of each other.

The EXE will have it's own heap
The DLL will have it's own heap
and these two things are entirely separate. malloc()ing from one heap and free()'ing on the other is sure recipe for corruption.

What can you do?

You have two choices

(i) You link all processes everything with RTL in DLL form.
Then all those 5 points above wont matter as each process is dealing with the _SAME_ state (inside the RTL in DLL form).
So if you had 1 EXE and 22 DLLs, you could fopen() in the EXE and fread() in all 22 DLL passing the same pointer around.
it wont matter as the 1 EXE and 22 DLLs will each refer to the _SINGLE_ state maintained by the RTL in DLL form.

(ii) Link with the static library but make sure that any resource that is allocated is changed in only one place.
So in the case of that strtok() parsing:
You might start the calls inside a DLL. But any further changes will be function calls in the _SAME_ DLL.
Effectively that DLL manages any changes to that resource (including deallocating that resource).
Other DLLs/EXE can have read-only access to that resource, but that is all.
They are not allowed to change the resource.
Any changes to the resource, _MUST_ occur inside the process that allocated the resource in the first place (be it fopen(),
malloc(), realloc(), new, new[], strtok() etc).
It is a discipline to write like this, and you might want to consider option (i) which gives you more freedom.

These 2 choices amount to the same thing.
Any given resource is always maintained in the one place.

Cheers

Stephen Howe

0 new messages