statically linking managed C++ into a C# project

L

Lee Crabtree

I'm starting work on what will eventually be a very, very LARGE project. A
lot of the project involves taking C/C++ class libraries and wrapping them
with managed C++. I'd like to minimize the number of DLLs I have (because
I'd like to keep my sanity). Is there some way to compile a managed C++ DLL
into a C# DLL, or am I just stuck consolidating the managed C++ into a
single DLL?

Lee
 
N

Nicholas Paldino [.NET/C# MVP]

Lee,

No, you can not statically link DLLs in .NET.

However, what you could do is when you create your wrapper for your C++
classes in a managed C++ assembly, instead of compiling that into an
assembly, compile it into a module.

Then, when compiling your C# project, you can reference the module and
have that built into the assembly.

You will have to compile these from the command line if using .NET 1.1,
or alter your MSBUILD file (your project file) if using .NET 2.0 or above
(or use the command line as well, if you wish).

On the C++ side, look at the /LN option. This will allow you to create
an MSIL module. Then, on the C# side, look at the /addmodule option, which
will allow you to specify an additional module to include in your assembly.

Hope this helps.
 
L

Lee Crabtree

You are a wonderful person.

Lee

Nicholas Paldino said:
Lee,

No, you can not statically link DLLs in .NET.

However, what you could do is when you create your wrapper for your C++
classes in a managed C++ assembly, instead of compiling that into an
assembly, compile it into a module.

Then, when compiling your C# project, you can reference the module and
have that built into the assembly.

You will have to compile these from the command line if using .NET 1.1,
or alter your MSBUILD file (your project file) if using .NET 2.0 or above
(or use the command line as well, if you wish).

On the C++ side, look at the /LN option. This will allow you to create
an MSIL module. Then, on the C# side, look at the /addmodule option,
which will allow you to specify an additional module to include in your
assembly.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Lee Crabtree said:
I'm starting work on what will eventually be a very, very LARGE project.
A lot of the project involves taking C/C++ class libraries and wrapping
them with managed C++. I'd like to minimize the number of DLLs I have
(because I'd like to keep my sanity). Is there some way to compile a
managed C++ DLL into a C# DLL, or am I just stuck consolidating the
managed C++ into a single DLL?

Lee
 
W

Willy Denoyette [MVP]

Note that it won't work this way.
/addmodule expects a "verifiable" netmodule, that is, a module produced with
/clr:safe option of C++/CLI.
Managed C++ code that wraps native C++ can't get compiled using /clr:safe
unless PInvoke interop is used, but PInvoke can not be used to wrap
unmanaged classes.

Willy.



Nicholas Paldino said:
Lee,

No, you can not statically link DLLs in .NET.

However, what you could do is when you create your wrapper for your C++
classes in a managed C++ assembly, instead of compiling that into an
assembly, compile it into a module.

Then, when compiling your C# project, you can reference the module and
have that built into the assembly.

You will have to compile these from the command line if using .NET 1.1,
or alter your MSBUILD file (your project file) if using .NET 2.0 or above
(or use the command line as well, if you wish).

On the C++ side, look at the /LN option. This will allow you to create
an MSIL module. Then, on the C# side, look at the /addmodule option,
which will allow you to specify an additional module to include in your
assembly.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Lee Crabtree said:
I'm starting work on what will eventually be a very, very LARGE project.
A lot of the project involves taking C/C++ class libraries and wrapping
them with managed C++. I'd like to minimize the number of DLLs I have
(because I'd like to keep my sanity). Is there some way to compile a
managed C++ DLL into a C# DLL, or am I just stuck consolidating the
managed C++ into a single DLL?

Lee
 
N

Nicholas Paldino [.NET/C# MVP]

Forgot about the verifiable part...


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Willy Denoyette said:
Note that it won't work this way.
/addmodule expects a "verifiable" netmodule, that is, a module produced
with /clr:safe option of C++/CLI.
Managed C++ code that wraps native C++ can't get compiled using /clr:safe
unless PInvoke interop is used, but PInvoke can not be used to wrap
unmanaged classes.

Willy.



Nicholas Paldino said:
Lee,

No, you can not statically link DLLs in .NET.

However, what you could do is when you create your wrapper for your
C++ classes in a managed C++ assembly, instead of compiling that into an
assembly, compile it into a module.

Then, when compiling your C# project, you can reference the module and
have that built into the assembly.

You will have to compile these from the command line if using .NET
1.1, or alter your MSBUILD file (your project file) if using .NET 2.0 or
above (or use the command line as well, if you wish).

On the C++ side, look at the /LN option. This will allow you to
create an MSIL module. Then, on the C# side, look at the /addmodule
option, which will allow you to specify an additional module to include
in your assembly.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Lee Crabtree said:
I'm starting work on what will eventually be a very, very LARGE project.
A lot of the project involves taking C/C++ class libraries and wrapping
them with managed C++. I'd like to minimize the number of DLLs I have
(because I'd like to keep my sanity). Is there some way to compile a
managed C++ DLL into a C# DLL, or am I just stuck consolidating the
managed C++ into a single DLL?

Lee
 
M

Mattias Sjögren

Willy,
/addmodule expects a "verifiable" netmodule

Why would it care about verifiability? I could /addmodule a mixed mode
module without problems here. With the 2.0 compiler I just had to
specify /platform:x86 for it to be accepted.


Mattias
 
W

Willy Denoyette [MVP]

Mattias Sjögren said:
Willy,


Why would it care about verifiability? I could /addmodule a mixed mode
module without problems here. With the 2.0 compiler I just had to
specify /platform:x86 for it to be accepted.


Mattias

Mattias,

Sorry for not being more explicit.
What I meant was that the way Nicholas explained would not work.
Now, what you did was simply adding a reference to a single "mixed mode"
netmodule (mixed mode = process specific), and you solved this with the
/platform:x86 option. That means your C# main program becomes machine
specific, no big deal though.
The problem is however that your netmodule must be distributed with your
main program assembly (.exe), a netmodule is referenced not statically
linked, right.
So, in the scenario of the OP, (remember he want's to reduce the number of
modules (DLL's)), we have:
1- C# assemblies, say a main program (entry point)
2- managed C++ code wrappers (mixed), and
3- native C++ code (wrapped classes) DLL's
building a netmodule for 2 doesn't solve the OP's problem, you still end
with three units of distribution, and it doesn't work anyway, you have to
link 2 and 3, as 2 calls into 3.
Ok, you could build a netmodule from 2 and 3, but you can't link a DLL from
this netmodule (linker returns: fatal error LNK1302: only support linking
safe .netmodules; unable to link ijw/native .netmodule).

That means at best you end with a .exe and a netmodule, and
- a netmodule is IMO not a valid unit of distribution
- is not loadable from unmanaged code, that would mean that still you need
to distribute the unmanaged code DLL, if used by unmanaged caller.
- and still you need the /platform:x86 option.

Willy.
 
W

Willy Denoyette [MVP]

Willy Denoyette said:
Mattias,

Sorry for not being more explicit.
What I meant was that the way Nicholas explained would not work.
Now, what you did was simply adding a reference to a single "mixed mode"
netmodule (mixed mode = process specific), and you solved this with the
/platform:x86 option. That means your C# main program becomes machine
specific, no big deal though.
The problem is however that your netmodule must be distributed with your
main program assembly (.exe), a netmodule is referenced not statically
linked, right.
So, in the scenario of the OP, (remember he want's to reduce the number of
modules (DLL's)), we have:
1- C# assemblies, say a main program (entry point)
2- managed C++ code wrappers (mixed), and
3- native C++ code (wrapped classes) DLL's
building a netmodule for 2 doesn't solve the OP's problem, you still end
with three units of distribution, and it doesn't work anyway, you have to
link 2 and 3, as 2 calls into 3.
Ok, you could build a netmodule from 2 and 3, but you can't link a DLL
from this netmodule (linker returns: fatal error LNK1302: only support
linking safe .netmodules; unable to link ijw/native .netmodule).

That means at best you end with a .exe and a netmodule, and
- a netmodule is IMO not a valid unit of distribution
- is not loadable from unmanaged code, that would mean that still you need
to distribute the unmanaged code DLL, if used by unmanaged caller.
- and still you need the /platform:x86 option.

Willy.

Sorry, but I forgot to tell that linking the managed and unmanaged C++
object modules (.obj) files into a mixed mode assembly (DLL), and refer to
this one from C# is IMO a better option.

Willy.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top