By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,247 Members | 1,427 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,247 IT Pros & Developers. It's quick & easy.

Can not reuse mixed-mode functions in VC++

P: n/a
By reuse, I mean a function in an assembly which is called in another
assembly.

By a mixed-mode function I mean a function whose signature has one or
more CLR types and one or more non-CLR types.

The problem:

I have a number of mixed-mode functions which I want reuse. These
functions revolve around converting a CLR String to a C++ std::string or
a C++ std::wstring, and vice versa, but of course they could
theoretically be anything.

In VS 2003 I was able to put these functions in a normal C++ class as
static functions and export the class. I was then able to call these
functions from another assembly. This worked fine, but because of the
loader lock bug, I did not pursue my use of C++ mixed-mode programming
in .NET assemblies.

In VS 2005 the loader lock bug is fixed and C++ .NET developers using
mixed-mode assemblies are back in business. Trying the exact same thing
I did in VS 2003, I now receive the error message telling me, for the
mixed-mode functions, that a function with the clr calling convention
can not be exported. Evidently mixed-mode functions are automatically
called with the clr calling convention.

I then decide to put my mixed-mode functions as static functions in a
ref class. This builds without error. However when I know try to call
this function from another assenbly, I receive an error message telling
me that "Candidate Functions Not Accessible".

So now we have the situation where one can not create a mixed-mode
reusable function in VC++ in VS 2005.

Has anyone else encountered this ? Am I the only one in the world that
finds such a simple usage to be a major imposition of VC++ in VS 2005 ?

I know I can duplicate my mixed-mode functions directly in every
assembly which needs to use them, but what a PITA ! I have already
reported this to Microsoft as a "bug", but I am curious to know if
anyone else has run into this problem before me, and to understand how
they reacted to it. Maybe there is a workaround to allow mixed-mode
function reuse but I have not found one.

I realize that programming C++ in .NET using mixed-mode assemblies has
some limitations, but this really appears extreme. C++ .NET programming
was supposed to get easier with this release of VS 2005, not harder.
While I applaud the efforts of integrating C++ with .NET, this sort of
new limitation was not what I expected.
Mar 21 '06 #1
Share this Question
Share on Google+
8 Replies


P: n/a
Hi Edward,
"Edward Diener" <ed*******************@tropicsoft.com> wrote in message
news:OS**************@tk2msftngp13.phx.gbl...
By reuse, I mean a function in an assembly which is called in another
assembly.

By a mixed-mode function I mean a function whose signature has one or more
CLR types and one or more non-CLR types.

The problem:

I have a number of mixed-mode functions which I want reuse. These
functions revolve around converting a CLR String to a C++ std::string or a
C++ std::wstring, and vice versa, but of course they could theoretically
be anything.

In VS 2003 I was able to put these functions in a normal C++ class as
static functions and export the class. I was then able to call these
functions from another assembly. This worked fine, but because of the
loader lock bug, I did not pursue my use of C++ mixed-mode programming in
.NET assemblies.

In VS 2005 the loader lock bug is fixed and C++ .NET developers using
mixed-mode assemblies are back in business. Trying the exact same thing I
did in VS 2003, I now receive the error message telling me, for the
mixed-mode functions, that a function with the clr calling convention can
not be exported. Evidently mixed-mode functions are automatically called
with the clr calling convention.

I then decide to put my mixed-mode functions as static functions in a ref
class. This builds without error. However when I know try to call this
function from another assenbly, I receive an error message telling me that
"Candidate Functions Not Accessible".

So now we have the situation where one can not create a mixed-mode
reusable function in VC++ in VS 2005.

Has anyone else encountered this ? Am I the only one in the world that
finds such a simple usage to be a major imposition of VC++ in VS 2005 ?

I know I can duplicate my mixed-mode functions directly in every assembly
which needs to use them, but what a PITA ! I have already reported this to
Microsoft as a "bug", but I am curious to know if anyone else has run into
this problem before me, and to understand how they reacted to it. Maybe
there is a workaround to allow mixed-mode function reuse but I have not
found one.

I realize that programming C++ in .NET using mixed-mode assemblies has
some limitations, but this really appears extreme. C++ .NET programming
was supposed to get easier with this release of VS 2005, not harder. While
I applaud the efforts of integrating C++ with .NET, this sort of new
limitation was not what I expected.


You ask a very interesing question: "Why can't I call a function having
arguments of a native type like std::string from another assembly?"

IMO, there is a straightforward answer to this question, but it needs some
explanations.

Assume you have some code like this one:

// Conversions.cpp
// compile with "CL /clr /LD conversions.cpp"
// output: mixed code assembly Conversions.dll
#include <string>

public ref class Conversions
{
public:
static void S2S(System::String^ s1, std::string& s2) { /* ... */ }
};

This code should compile as expected, however, it would not give you the
expected result!

The code below looks like a suitable client:

// ConversionsClient.cpp
// compile with "CL /clr ConversionsClient.cpp"
#using "Conversions.dll"
#include <string>
int main()
{
std::string s;
Conversions::S2S("asdf", s);
}

If you try to compile this code, you will get a disappointing error message:

error C3767: 'Conversions::S2S': candidate function(s) not accessible

Why is a public static function S2S of a public type Convesions not
accessible?

To use the native type std::string in managed code, the compiler generates a
managed value type std::string in the assembly where std::string is used.
This managed wrapper value type is private, therefore, the Conversions::S2S
cannot be called from outside the assembly even though it is a public
function of a public type.

At the first view it seems, key to the solution is to make sure the compiler
generates a public type for std::string, in theory this is possible, however
it would not help to solve the problem. In fact the native wrapper type has
been defined as a private type for some good reasons.

Assume the native wrapper type for std::string was public. To call S2S, one
would have to pass a tracking handle to a System::String, defined in
mscolib.dll, and a value of the type std::string defined in the assembly
Conversions.dll. The std::string type that we pass in ConversionsClient.cpp
is a different one! It is the native wrapper type defined in
ConversionsClient.cpp - not the native wapper type defined in
Conversions.dll. Therefore, the parameters would not match.

So how can we solve this problem?

The origin of the problem is the fact, that type identity rules of .NET do
not allways mix well with the type identity rules of native C++. To solve
this problem, you can switch back to the world of native code sharing
without loosing you managed code features. Simply create a mixed code static
library:

Create a static mixed code library from the code :

// ConversionsLib.cpp
// compile with "CL /c /clr ConversionsLib.cpp"
// make lib with "LIB ConversionsLib.obj"
// output: mixed code static library ConversionsLib.lib

#include <string>
void S2S(System::String^ s1, std::string& s2) { /* ... */ }

Create a client from the code below.

// ConversionsLibClient.cpp
// compile with "CL /clr ConversionsLibClient.cpp"
#include <string>

#pragma comment (lib, "ConversionsLib.lib")
void S2S(System::String^ s1, std::string& s2);

int main()
{
std::string s;
S2S("asdff", s);
}

Conclusion: Beware the different type identity rules. Native types are
identifies by their namespace-qualified typename, managed types are
identified by their assembly- and namespace-qualifies typename. If you need
native type identity rules, use native code sharing features, if you need
managed type identity, use managed code sharing features.
Mar 21 '06 #2

P: n/a
Marcus Heege wrote:
Hi Edward,
"Edward Diener" <ed*******************@tropicsoft.com> wrote in message
news:OS**************@tk2msftngp13.phx.gbl...
By reuse, I mean a function in an assembly which is called in another
assembly.

By a mixed-mode function I mean a function whose signature has one or more
CLR types and one or more non-CLR types.

The problem:

I have a number of mixed-mode functions which I want reuse. These
functions revolve around converting a CLR String to a C++ std::string or a
C++ std::wstring, and vice versa, but of course they could theoretically
be anything.

In VS 2003 I was able to put these functions in a normal C++ class as
static functions and export the class. I was then able to call these
functions from another assembly. This worked fine, but because of the
loader lock bug, I did not pursue my use of C++ mixed-mode programming in
.NET assemblies.

In VS 2005 the loader lock bug is fixed and C++ .NET developers using
mixed-mode assemblies are back in business. Trying the exact same thing I
did in VS 2003, I now receive the error message telling me, for the
mixed-mode functions, that a function with the clr calling convention can
not be exported. Evidently mixed-mode functions are automatically called
with the clr calling convention.

I then decide to put my mixed-mode functions as static functions in a ref
class. This builds without error. However when I know try to call this
function from another assenbly, I receive an error message telling me that
"Candidate Functions Not Accessible".

So now we have the situation where one can not create a mixed-mode
reusable function in VC++ in VS 2005.

Has anyone else encountered this ? Am I the only one in the world that
finds such a simple usage to be a major imposition of VC++ in VS 2005 ?

I know I can duplicate my mixed-mode functions directly in every assembly
which needs to use them, but what a PITA ! I have already reported this to
Microsoft as a "bug", but I am curious to know if anyone else has run into
this problem before me, and to understand how they reacted to it. Maybe
there is a workaround to allow mixed-mode function reuse but I have not
found one.

I realize that programming C++ in .NET using mixed-mode assemblies has
some limitations, but this really appears extreme. C++ .NET programming
was supposed to get easier with this release of VS 2005, not harder. While
I applaud the efforts of integrating C++ with .NET, this sort of new
limitation was not what I expected.
You ask a very interesing question: "Why can't I call a function having
arguments of a native type like std::string from another assembly?"

IMO, there is a straightforward answer to this question, but it needs some
explanations.

Assume you have some code like this one:

// Conversions.cpp
// compile with "CL /clr /LD conversions.cpp"
// output: mixed code assembly Conversions.dll
#include <string>

public ref class Conversions
{
public:
static void S2S(System::String^ s1, std::string& s2) { /* ... */ }
};

This code should compile as expected, however, it would not give you the
expected result!

The code below looks like a suitable client:

// ConversionsClient.cpp
// compile with "CL /clr ConversionsClient.cpp"
#using "Conversions.dll"
#include <string>
int main()
{
std::string s;
Conversions::S2S("asdf", s);
}

If you try to compile this code, you will get a disappointing error message:

error C3767: 'Conversions::S2S': candidate function(s) not accessible

Why is a public static function S2S of a public type Convesions not
accessible?

To use the native type std::string in managed code, the compiler generates a
managed value type std::string in the assembly where std::string is used.
This managed wrapper value type is private, therefore, the Conversions::S2S
cannot be called from outside the assembly even though it is a public
function of a public type.

At the first view it seems, key to the solution is to make sure the compiler
generates a public type for std::string, in theory this is possible, however
it would not help to solve the problem. In fact the native wrapper type has
been defined as a private type for some good reasons.

Assume the native wrapper type for std::string was public. To call S2S, one
would have to pass a tracking handle to a System::String, defined in
mscolib.dll, and a value of the type std::string defined in the assembly
Conversions.dll. The std::string type that we pass in ConversionsClient.cpp
is a different one! It is the native wrapper type defined in
ConversionsClient.cpp - not the native wapper type defined in
Conversions.dll. Therefore, the parameters would not match.


Since we are talking about the exact same C++ type, why would the CLR
wrapper for this type ever differ from assembly to assembly ? That it
would makes no logical sense. If I have a function which passes an
"int", which is a C++ type, between assemblies the native wrapper type
is the same, is it not ? Why should it be any different for a C++
user-defined type once I give CLR a header file at which to look for
that type's declaration. Certainly CLR can get it right that the same
C++ type becomes the same native wrapper type no matter what assembly it
is in.

So how can we solve this problem?

The origin of the problem is the fact, that type identity rules of .NET do
not allways mix well with the type identity rules of native C++. To solve
this problem, you can switch back to the world of native code sharing
without loosing you managed code features. Simply create a mixed code static
library:


So you are simply saying that a static library compiled as CLR code
works but that an assembly compiled as CLR code does not. Fine, but that
still does not explain why such an anomaly should be part of .NET C++
programming.

Of course I do not know the full technical details but I do not think
the VC++ team at Microsoft got this right. Being able to reuse C++ code,
whether it refers to a CLR type or a native C++ type, between assemblies
seems really necessary for effective C++ programming in .NET. Having a
hack which says that this can only be done if the assembly is created as
a static library compiled as CLR code as opposed to a normal .NET
assembly seems really backward to me.

I do not even know how to specify such a project in the Visual Studio
2005 IDE. I have been using the Express edition but have received the
standard edition and will be installing it shortly. I see no project
type in the Express edition which creates a CLR static library. Perhaps
there is a project type like that in the standard edition. Any clues on
how to do this in the IDE, and to tell my other assemblies to link with
this CLR static library, will be greatly appreciated.
Mar 21 '06 #3

P: n/a
"Edward Diener" <ed*******************@tropicsoft.com> wrote in message
news:%2****************@TK2MSFTNGP14.phx.gbl...
Since we are talking about the exact same C++ type, why would the CLR
wrapper for this type ever differ from assembly to assembly ? That it
would makes no logical sense.
There are differences in type identity: Assume you have two classic C++
headers defining a class C. To the native C++ compiler and linker, these
would be the same. You can include one header in one source file of your
poject and the other header in the other source file and link both together.
The result would likely be chaos.

In .NET, this is different: A type's identity is bound to the assembly:

Two types named Foo defined in two different assemblies are two different
types.
Two types named Foo defined in two different versions of the same assembly
are two different types.

It is important to keep this in mind when writing .NET code with any .NET
language.

There is no way to define a .NET type without an implicit binding to the
assembly in which it is defined: .NET Types are always identified via the
assembly in which they are defined.
If I have a function which passes an "int", which is a C++ type, between
assemblies the native wrapper type is the same, is it not ?
For the primitives, the situation is different. C++/CLI does not need to
create wrapper types for them, because there are wrapper types already. For
the type int, this is System.Int32 from the assembly mscorlib. If you define
a function with an int argument, then both caller and callee see this as an
argument of type System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=...
Why should it be any different for a C++ user-defined type once I give CLR
a header file at which to look for that type's declaration.
For types that do not have an equivalent type in mscorlib, C++/CLI defines a
wrapper type. The identity of this wrapper type is bound to the assembly in
which it is defined.
Certainly CLR can get it right that the same C++ type becomes the same
native wrapper type no matter what assembly it is in.
The answer is: No
So you are simply saying that a static library compiled as CLR code works
but that an assembly compiled as CLR code does not. Fine, but that still
does not explain why such an anomaly should be part of .NET C++
programming.
A static library is not a .NET assembly, therefore it does not give types
defined in it an identity. A static library is just a container for native
code, managed code, and managed type definitions that can be linked into an
assembly. Once it is linked into an assembly, it is managed types get their
identity from the assembly in which they end up.
Of course I do not know the full technical details but I do not think the
VC++ team at Microsoft got this right. Being able to reuse C++ code,
whether it refers to a CLR type or a native C++ type, between assemblies
seems really necessary for effective C++ programming in .NET.
I fell your pain, but the rules are as they are. You can not share native
type identity accross assemblies.
Having a hack which says that this can only be done if the assembly is
created as a static library compiled as CLR code as opposed to a normal
.NET assembly seems really backward to me.
I do not consider static libraries to be a hack. They are still very useful.
I do not even know how to specify such a project in the Visual Studio 2005
IDE. I have been using the Express edition but have received the standard
edition and will be installing it shortly. I see no project type in the
Express edition which creates a CLR static library. Perhaps there is a
project type like that in the standard edition. Any clues on how to do
this in the IDE, and to tell my other assemblies to link with this CLR
static library, will be greatly appreciated.


To build a static library in Visual Studio, choose Visual C++ projects /
Win32 / Win32 project. Then switch to application settings and choose
"Static Library". Once you have done that, you can change the project
settings / Configuration Properties / General / Common Language Runtinme
support to "Common Language Runtime Support (/clr)" so that you can write
managed code.

To link the lib into an assembly you should make sure that the generated lib
file is in the lib path. By default, the lib's project settings are
configured so that the output directory is
"$(SolutionDir)$(ConfigurationName)". In your assembly's linker settings you
can add this to the lib path. Furthermore, you can add the lib to the linker
inputs, or in your code you can write

#pragma comment (lib, "YourManagedStaticLib.lib")

Hope this helps.

Marcus Heege

Mar 21 '06 #4

P: n/a
Marcus Heege wrote:
"Edward Diener" <ed*******************@tropicsoft.com> wrote in message
news:%2****************@TK2MSFTNGP14.phx.gbl...
Since we are talking about the exact same C++ type, why would the CLR
wrapper for this type ever differ from assembly to assembly ? That it
would makes no logical sense.
There are differences in type identity: Assume you have two classic C++
headers defining a class C. To the native C++ compiler and linker, these
would be the same. You can include one header in one source file of your
poject and the other header in the other source file and link both together.
The result would likely be chaos.


OK, understood.

In .NET, this is different: A type's identity is bound to the assembly:

Two types named Foo defined in two different assemblies are two different
types.
Two types named Foo defined in two different versions of the same assembly
are two different types.
OK, I see what you are explaining.

It is important to keep this in mind when writing .NET code with any .NET
language.
It sounds to me that if I can wrap a native C++ type, such as
std::string to a CLR value class, I can then pass that class to another
assembly and operate on it. Can this be done, with std::string or any
other native C++ type, in order to pass it back and forth between
assemblies ? It seems like it must be possible if you are telling me
that CLR is doing these under the covers whenever I refer to a standard
C++ type in code that is compiled with /clr.

If so it appears to me that MS could have wrapped any standard C++ type
into an assembly and provided that as a way of passing standard C++
types between assembles. They could not have done it with templates,
because these are not types, but they could have done it with
std::string because that is a type even if it is an instantiated template.

There is no way to define a .NET type without an implicit binding to the
assembly in which it is defined: .NET Types are always identified via the
assembly in which they are defined.
If I have a function which passes an "int", which is a C++ type, between
assemblies the native wrapper type is the same, is it not ?


For the primitives, the situation is different. C++/CLI does not need to
create wrapper types for them, because there are wrapper types already. For
the type int, this is System.Int32 from the assembly mscorlib. If you define
a function with an int argument, then both caller and callee see this as an
argument of type System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=...
Why should it be any different for a C++ user-defined type once I give CLR
a header file at which to look for that type's declaration.


For types that do not have an equivalent type in mscorlib, C++/CLI defines a
wrapper type. The identity of this wrapper type is bound to the assembly in
which it is defined.
Certainly CLR can get it right that the same C++ type becomes the same
native wrapper type no matter what assembly it is in.


The answer is: No
So you are simply saying that a static library compiled as CLR code works
but that an assembly compiled as CLR code does not. Fine, but that still
does not explain why such an anomaly should be part of .NET C++
programming.


A static library is not a .NET assembly, therefore it does not give types
defined in it an identity. A static library is just a container for native
code, managed code, and managed type definitions that can be linked into an
assembly. Once it is linked into an assembly, it is managed types get their
identity from the assembly in which they end up.


Thanks for this explanation. I know of course what a non-.NET static
library is. I had not appreciated that I could create such a static
library, tell it to compile with /clr, and link it to an assembly. At
least this is better than having to add the same functions to every
assembly, even though I am still duplicating the same code for each
assembly.

The rest of your instructions for creating a static library compiled
with /clr and linking it to an assembly I understand.
Mar 21 '06 #5

P: n/a
Edward Diener wrote:
It sounds to me that if I can wrap a native C++ type, such as
std::string to a CLR value class


My understanding is that you can not. Only the compiler can. Value
classes don't support default constructors, copy constructors,
assignment operators, destructors, which are all essencial part of
native C++ types. The compiler can still wrap it as a private
non-accessible type. The compiler can do anything, because its output is
machine code. But if you want to use a public type in an assembly, you
have to play nice with the rules of .NET.

The reason .NET value types don't allow custom construction, destruction
and assignment is efficiency. Value classes are essencially like C++ POD
types, which can be constructed using memset, can be assigned using
memcpy, and can be destructed without doing anything at all. An array of
value types behaves like a large C struct, not like a C++ class. You can
still have member functions, but you must explicitly call them. They're
not called automatically when you create, assign or destruct an object.

When the compiler wraps std::string into a CLR value class, its
constrcutors, destructor and operators are substituted with dedicated
member functions, which are called explicitly by the generated IL code.
It's like programming C++ the way that you call the constructor
Construct, the assignment operator Assign, and the destructor Destruct,
and you explicitly call them from your code.

Tom
Mar 21 '06 #6

P: n/a
Tamas Demjen wrote:
Edward Diener wrote:
It sounds to me that if I can wrap a native C++ type, such as
std::string to a CLR value class


My understanding is that you can not. Only the compiler can. Value
classes don't support default constructors, copy constructors,
assignment operators, destructors, which are all essencial part of
native C++ types. The compiler can still wrap it as a private
non-accessible type. The compiler can do anything, because its output is
machine code. But if you want to use a public type in an assembly, you
have to play nice with the rules of .NET.

The reason .NET value types don't allow custom construction, destruction
and assignment is efficiency. Value classes are essencially like C++ POD
types, which can be constructed using memset, can be assigned using
memcpy, and can be destructed without doing anything at all. An array of
value types behaves like a large C struct, not like a C++ class. You can
still have member functions, but you must explicitly call them. They're
not called automatically when you create, assign or destruct an object.

When the compiler wraps std::string into a CLR value class, its
constrcutors, destructor and operators are substituted with dedicated
member functions, which are called explicitly by the generated IL code.
It's like programming C++ the way that you call the constructor
Construct, the assignment operator Assign, and the destructor Destruct,
and you explicitly call them from your code.


Thanks for all the information. I should have known it myself since I
have used value types before in Managed C++.

I do hope that C++ .NET will change and that "C++ value types", with
differences from CLR value types to allow C++ user-defined types to be
embedded in them, will be added so that native C++ types can be passed
from assembly to assembly. Of course these "C++ value types" would not
be accesible from other .NET languages, just as C++ native types are
not, but they would be useful for C++ .NET programmers in mixed-mode
programming who want to create reusable CLR functions dealing with
native C++ types. I have found this a PITA that this can not be done,
although the static lib compiled with CLR is a workaround which I will
use. But it of course duplicates code unnecessarily.
Mar 21 '06 #7

P: n/a
Marcus Heege wrote:
"Edward Diener" <ed*******************@tropicsoft.com> wrote in message
I do not even know how to specify such a project in the Visual Studio 2005
IDE. I have been using the Express edition but have received the standard
edition and will be installing it shortly. I see no project type in the
Express edition which creates a CLR static library. Perhaps there is a
project type like that in the standard edition. Any clues on how to do
this in the IDE, and to tell my other assemblies to link with this CLR
static library, will be greatly appreciated.
To build a static library in Visual Studio, choose Visual C++ projects /
Win32 / Win32 project. Then switch to application settings and choose
"Static Library". Once you have done that, you can change the project
settings / Configuration Properties / General / Common Language Runtinme
support to "Common Language Runtime Support (/clr)" so that you can write
managed code.


I have done this successfully.

To link the lib into an assembly you should make sure that the generated lib
file is in the lib path. By default, the lib's project settings are
configured so that the output directory is
"$(SolutionDir)$(ConfigurationName)". In your assembly's linker settings you
can add this to the lib path. Furthermore, you can add the lib to the linker
inputs, or in your code you can write

#pragma comment (lib, "YourManagedStaticLib.lib")


In Project Dependencies I made the static library a dependency of the
assemmbly. When I look at my linker command line for the assembly I see
the generated static library added to the list of lib files at the end
of the command. Evidently the IDE is smart enough to do this for me
without my having to specify the static library as an Additional Dependency.

However when I build my assembly I get LNK2020 errors of Unresolved
Token for the particular CLR static functions in the static library
which I am trying to reuse. Do you have any ideas what is wrong ?

I have double-checked the static library properties and I am definitely
building with /clr ( in my case since I am porting routines from VS 2003
it is /clr:oldSyntax ). Unfortunately when I tried to use IL DASM to
check on the static library, it showed nothing. I wonder if that is
because it can not disassemble static libs or because there really is no
CLR tokens in it. I have no idea now why it does not find my CLR tokens
in the static lib.
Mar 26 '06 #8

P: n/a
Edward Diener wrote:
Marcus Heege wrote:
"Edward Diener" <ed*******************@tropicsoft.com> wrote in message
I do not even know how to specify such a project in the Visual Studio
2005 IDE. I have been using the Express edition but have received the
standard edition and will be installing it shortly. I see no project
type in the Express edition which creates a CLR static library.
Perhaps there is a project type like that in the standard edition.
Any clues on how to do this in the IDE, and to tell my other
assemblies to link with this CLR static library, will be greatly
appreciated.


To build a static library in Visual Studio, choose Visual C++ projects
/ Win32 / Win32 project. Then switch to application settings and
choose "Static Library". Once you have done that, you can change the
project settings / Configuration Properties / General / Common
Language Runtinme support to "Common Language Runtime Support (/clr)"
so that you can write managed code.


I have done this successfully.

To link the lib into an assembly you should make sure that the
generated lib file is in the lib path. By default, the lib's project
settings are configured so that the output directory is
"$(SolutionDir)$(ConfigurationName)". In your assembly's linker
settings you can add this to the lib path. Furthermore, you can add
the lib to the linker inputs, or in your code you can write

#pragma comment (lib, "YourManagedStaticLib.lib")


In Project Dependencies I made the static library a dependency of the
assemmbly. When I look at my linker command line for the assembly I see
the generated static library added to the list of lib files at the end
of the command. Evidently the IDE is smart enough to do this for me
without my having to specify the static library as an Additional
Dependency.

However when I build my assembly I get LNK2020 errors of Unresolved
Token for the particular CLR static functions in the static library
which I am trying to reuse. Do you have any ideas what is wrong ?


When I changed the class in my static library from __gc to __nogc,
everything then worked correctly. So please ignore this follow up.
Mar 26 '06 #9

This discussion thread is closed

Replies have been disabled for this discussion.