471,338 Members | 899 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,338 software developers and data experts.

Link Error 2028 2029 when using CString in C++/CLI

Hello Newsgroup,

I have a link error that I did not manage to fix.

I basically consume a VC 8.0 C++ dll that exports a class with a
method containing CString declaration as follows:

class WarnErr
{
//...
CString WarnErr::getReadableCode (long nCode)
{
//...
}

When using the method in another project (C++/CLI) to write a RTCW,
the linker fails with the following error:

Error 2 error LNK2028: unresolved token (0A00000F) "public: static
class ATL::CStringT<char,class StrTraitMFC_DLL<char,class
ATL::ChTraitsCRT<char __cdecl
lala_McsOOP::WarnErr::getReadableCode(long)" (?
getReadableCode@WarnErr@lala_McsOOP@@$$FSA?AV?$CSt ringT@DV?
$StrTraitMFC_DLL@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@J@ Z) referenced in
function "public: class System::String ^ __clrcall
lala::Spectrometer::RTCW::SpectrometerException::T oString(void)" (?
ToString@SpectrometerException@RTCW@Spectrometer@l ala@@$$FQ$AAMP
$AAVString@System@@XZ) SpectrometerException.obj
Does anybody know how to fix this issue. Or is there any other good
practice passing strings from unmanaged libs tto managed libs?

Thanks for your help!

Jun 1 '07 #1
4 5390
When using the method in another project (C++/CLI) to write a RTCW,
the linker fails with the following error:

Error 2 error LNK2028: unresolved token (0A00000F) "public: static
class ATL::CStringT<char,class StrTraitMFC_DLL<char,class
ATL::ChTraitsCRT<char __cdecl
lala_McsOOP::WarnErr::getReadableCode(long)" (?
getReadableCode@WarnErr@lala_McsOOP@@$$FSA?AV?$CSt ringT@DV?
$StrTraitMFC_DLL@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@J@ Z) referenced in
function "public: class System::String ^ __clrcall
lala::Spectrometer::RTCW::SpectrometerException::T oString(void)" (?
ToString@SpectrometerException@RTCW@Spectrometer@l ala@@$$FQ$AAMP
$AAVString@System@@XZ) SpectrometerException.obj
Does anybody know how to fix this issue. Or is there any other good
practice passing strings from unmanaged libs tto managed libs?
I suggest that the only things you should pass across module boundaries are:
(1) blocks of raw data (pointer and length)
(2) interface pointers
DCOM shows that by following these two rules you can have very powerful yet
stable interaction between all kinds of different components. Decoupling in
this way is also good for encapsulation, testability, and stability.

Trying to share class objects between unmanaged modules usually fails due to
ODR violations.
>
Thanks for your help!

Jun 1 '07 #2
On Jun 1, 9:14 pm, "Ben Voigt [C++ MVP]" <r...@nospam.nospamwrote:
When using the method in another project (C++/CLI) to write a RTCW,
the linker fails with the following error:
Error 2 error LNK2028: unresolved token (0A00000F) "public: static
class ATL::CStringT<char,class StrTraitMFC_DLL<char,class
ATL::ChTraitsCRT<char __cdecl
lala_McsOOP::WarnErr::getReadableCode(long)" (?
getReadableCode@WarnErr@lala_McsOOP@@$$FSA?AV?$CSt ringT@DV?
$StrTraitMFC_DLL@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@J@ Z) referenced in
function "public: class System::String ^ __clrcall
lala::Spectrometer::RTCW::SpectrometerException::T oString(void)" (?
ToString@SpectrometerException@RTCW@Spectrometer@l ala@@$$FQ$AAMP
$AAVString@System@@XZ) SpectrometerException.obj
Does anybody know how to fix this issue. Or is there any other good
practice passing strings from unmanaged libs tto managed libs?

I suggest that the only things you should pass across module boundaries are:
(1) blocks of raw data (pointer and length)
(2) interface pointers
DCOM shows that by following these two rules you can have very powerful yet
stable interaction between all kinds of different components. Decoupling in
this way is also good for encapsulation, testability, and stability.

Trying to share class objects between unmanaged modules usually fails due to
ODR violations.
Thanks for your help!
Hello Ben,

thanks for your comment on this issue. I generally agree with your
opinion as it is good practice.
However, there a couple of good reasons for CString as well and I was
under the opinion that passing basic types like strings isn't a big
deal anymore.
Let us consider the lib I'm trying to incorporate with is sort of fix
and will only get subject for changes if any other approach fails.

Can you point me to pretty good practices of passing strings of
individual length's from unmanaged code to C++/CLI code?

Thanks again,

Sebastian Dau

Jun 4 '07 #3
Does anybody know how to fix this issue. Or is there any other good
practice passing strings from unmanaged libs tto managed libs?

I suggest that the only things you should pass across module boundaries
are:
(1) blocks of raw data (pointer and length)
(2) interface pointers
DCOM shows that by following these two rules you can have very powerful
yet
stable interaction between all kinds of different components. Decoupling
in
this way is also good for encapsulation, testability, and stability.

Trying to share class objects between unmanaged modules usually fails due
to
ODR violations.
Thanks for your help!

Hello Ben,

thanks for your comment on this issue. I generally agree with your
opinion as it is good practice.
However, there a couple of good reasons for CString as well and I was
under the opinion that passing basic types like strings isn't a big
deal anymore.
Let us consider the lib I'm trying to incorporate with is sort of fix
and will only get subject for changes if any other approach fails.

Can you point me to pretty good practices of passing strings of
individual length's from unmanaged code to C++/CLI code?
First up, you must compile all code using the unmanaged DLL's classes
without /clr and with the same compiler version used by the DLL. Otherwise
the ODR is violated. This is not a recommendation, it is an absolute
requirement to get any sort of reasonable behavior.

Next, you should use fundamental types such as wchar_t* or char* to pass
data between those files compiled without /clr and the ones compiled with.
The definition of those types aren't changed by /clr or the compiler
version. These convert to and from the std::string and CString variants in
the usual way.

Then, use the following functions to get the data to/from .NET
System::String:

PtrToStringChars
System::Runtime::InteropServices::Marshal::PtrToSt ring{Ansi|Auto|BSTR|Uni}

If you do that, everything should link and run without problems. If the DLL
was compiled using an earlier version of the compiler, then the static lib
wrappers described in "First up" should use extern "C" functions. You
should probably do that anyway.
>
Thanks again,

Sebastian Dau

Jun 4 '07 #4
On Jun 4, 3:30 pm, "Ben Voigt [C++ MVP]" <r...@nospam.nospamwrote:
Does anybody know how to fix this issue. Or is there any other good
practice passing strings from unmanaged libs tto managed libs?
I suggest that the only things you should pass across module boundaries
are:
(1) blocks of raw data (pointer and length)
(2) interface pointers
DCOM shows that by following these two rules you can have very powerful
yet
stable interaction between all kinds of different components. Decoupling
in
this way is also good for encapsulation, testability, and stability.
Trying to share class objects between unmanaged modules usually fails due
to
ODR violations.
Thanks for your help!
Hello Ben,
thanks for your comment on this issue. I generally agree with your
opinion as it is good practice.
However, there a couple of good reasons for CString as well and I was
under the opinion that passing basic types like strings isn't a big
deal anymore.
Let us consider the lib I'm trying to incorporate with is sort of fix
and will only get subject for changes if any other approach fails.
Can you point me to pretty good practices of passing strings of
individual length's from unmanaged code to C++/CLI code?

First up, you must compile all code using the unmanaged DLL's classes
without /clr and with the same compiler version used by the DLL. Otherwise
the ODR is violated. This is not a recommendation, it is an absolute
requirement to get any sort of reasonable behavior.

Next, you should use fundamental types such as wchar_t* or char* to pass
data between those files compiled without /clr and the ones compiled with.
The definition of those types aren't changed by /clr or the compiler
version. These convert to and from the std::string and CString variants in
the usual way.

Then, use the following functions to get the data to/from .NET
System::String:

PtrToStringChars
System::Runtime::InteropServices::Marshal::PtrToSt ring{Ansi|Auto|BSTR|Uni}

If you do that, everything should link and run without problems. If the DLL
was compiled using an earlier version of the compiler, then the static lib
wrappers described in "First up" should use extern "C" functions. You
should probably do that anyway.
Thanks again,
Sebastian Dau
Thanks, Ben I'll give that a try and see how it works.

Jun 4 '07 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Andy | last post: by
19 posts views Thread by ashmangat | last post: by
reply views Thread by Bernie Hunt | last post: by
2 posts views Thread by adsci | last post: by
reply views Thread by =?Utf-8?B?REx1ZWNr?= | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.