Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions docs/build/reference/netmodule-files-as-linker-input.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,40 @@
---
title: ".netmodule Files as Linker Input"
ms.date: "05/16/2019"
helpviewer_keywords: ["MSIL linking", "linking [C++], modules", ".netmodules", "modules, Visual C++"]
title: ".netmodule files as linker input"
description: "Describes how to use mixed .obj and .netmodule files as linker input when creating .NET assemblies."
ms.date: "01/30/2020"
helpviewer_keywords: ["MSIL linking", "linking [C++], modules", ".netmodule files", "modules, Visual C++"]
ms.assetid: a4bcbe8a-4255-451d-853b-f88cfd82f4e1
no-loc: [obj, netmodule, clr, pure, safe]
---
# .netmodule Files as Linker Input
# .netmodule files as linker input

link.exe now accepts MSIL .obj and .netmodules as input. The output file produced by the linker is an assembly or a .netmodule with no run-time dependency on any of the .obj or .netmodules that were input to the linker.
link.exe accepts MSIL *`.obj`* and *`.netmodule`* files as input. The output file produced by the linker is an assembly or a *`.netmodule`* file with no run-time dependency on any of the *`.obj`* or *`.netmodule`* files that were input to the linker.

.netmodules are created by the MSVC compiler with [/LN (Create MSIL Module)](ln-create-msil-module.md) or by the linker with [/NOASSEMBLY (Create a MSIL Module)](noassembly-create-a-msil-module.md). .objs are always created in a Visual C++ compilation. For other Visual Studio compilers, use the **/target:module** compiler option.
## Remarks

You must pass to the linker the .obj file from the Visual C++ compilation that created the .netmodule. Passing in a .netmodule is no longer supported because the **/clr:pure** and **/clr:safe** compiler options are deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017 and later.
*`.netmodule`* files are created by the MSVC compiler with [/LN (Create MSIL module)](ln-create-msil-module.md) or by the linker with [/NOASSEMBLY (Create a MSIL Module)](noassembly-create-a-msil-module.md). *`.obj`* files are always created in a C++ compilation. For other Visual Studio compilers, use the **/target:module** compiler option.

For information on how to invoke the linker from the command line, see [Linker Command-Line Syntax](linking.md), [Use the MSVC toolset from the command line](../building-on-the-command-line.md), and [Set the Path and Environment Variables for Command-Line Builds](../setting-the-path-and-environment-variables-for-command-line-builds.md).
The linker must be passed the *`.obj`* file from the C++ compilation that created the *`.netmodule`*. Passing in a *`.netmodule`* is no longer supported because the **/clr:pure** and **/clr:safe** compiler options are deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017 and later.

Passing a .netmodule or .dll file to the linker that was compiled by the MSVC compiler with **/clr** can result in a linker error. For more information, see [Choosing the Format of .netmodule Input Files](choosing-the-format-of-netmodule-input-files.md).
For information on how to invoke the linker from the command line, see [Linker command-line syntax](linking.md), [Use the MSVC toolset from the command line](../building-on-the-command-line.md), and [Set the path and environment variables for command-line builds](../setting-the-path-and-environment-variables-for-command-line-builds.md).

The linker accepts native .obj files as well as MSIL .obj files compiled with **/clr**. When passing mixed .objs in the same build, the verifiability of the resulting output file will, by default, be equal to the lowest level of verifiability of the input modules.
Passing a *`.netmodule`* or *`.dll`* file to the linker that was compiled by the MSVC compiler with **/clr** can result in a linker error. For more information, see [Choosing the format of .netmodule input files](choosing-the-format-of-netmodule-input-files.md).

If you currently have an application that is composed of two or more assemblies and you want the application to be contained in one assembly, you must recompile the assemblies and then link the .objs or .netmodules to produce a single assembly.
The linker accepts both native *`.obj`* files and MSIL *`.obj`* files compiled with **/clr**. You can pass mixed *`.obj`* files in the same build. The resulting output file's default verifiability is the same as the lowest input module's verifiability.

You must specify an entry point using [/ENTRY (Entry-Point Symbol)](entry-entry-point-symbol.md) when creating an executable image.
You can change an application that's composed of two or more assemblies to be contained in one assembly. Recompile the assemblies' sources, and then link the *`.obj`* files or *`.netmodule`* files to produce a single assembly.

When linking with an MSIL .obj or .netmodule file, use [/LTCG (Link-time Code Generation)](ltcg-link-time-code-generation.md), otherwise when the linker encounters the MSIL .obj or .netmodule, it will restart the link with /LTCG.
Specify an entry point using [/ENTRY (Entry-point symbol)](entry-entry-point-symbol.md) when creating an executable image.

MSIL .obj or .netmodule files can also be passed to cl.exe.
When linking with an MSIL *`.obj`* or *`.netmodule`* file, use [/LTCG (Link-time code generation)](ltcg-link-time-code-generation.md), otherwise when the linker encounters the MSIL *`.obj`* or *`.netmodule`*, it will restart the link with **/LTCG**. You'll see an informational message that the link is restarting. You can ignore this message, but to improve linker performance, explicitly specify **/LTCG**.

Input MSIL .obj or .netmodule files cannot have embedded resources. A resource is embedded in an output file (module or assembly) with [/ASSEMBLYRESOURCE (Embed a Managed Resource)](assemblyresource-embed-a-managed-resource.md) linker option or with the **/resource** compiler option in other Visual Studio compilers.
MSIL *`.obj`* or *`.netmodule`* files can also be passed to cl.exe.

When performing MSIL linking, and if you do not also specify [/LTCG (Link-time Code Generation)](ltcg-link-time-code-generation.md), you will see an informational message reporting that the link is restarting. This message can be ignored, but to improve linker performance with MSIL linking, explicitly specify **/LTCG**.
Input MSIL *`.obj`* or *`.netmodule`* files can't have embedded resources. Embed resources in an output module or assembly file by using the [/ASSEMBLYRESOURCE (Embed a managed resource)](assemblyresource-embed-a-managed-resource.md) linker option. Or, use the **/resource** compiler option in other Visual Studio compilers.

## Example
## Examples

In C++ code the **catch** block of a corresponding **try** will be invoked for a non System exception. However, by default, the CLR wraps non-System exceptions with <xref:System.Runtime.CompilerServices.RuntimeWrappedException>. When an assembly is created from Visual C++ and non-Visual C++ modules and you want a **catch** block in C++ code to be invoked from its corresponding **try** clause when the **try** block throws a non-System exception, you must add the `[assembly:System::Runtime::CompilerServices::RuntimeCompatibility(WrapNonExceptionThrows=false)]` attribute to the source code for the non C++ modules.
In C++ code, the **`catch`** block of a corresponding **`try`** will be invoked for a non-`System` exception. However, by default, the CLR wraps non-`System` exceptions with <xref:System.Runtime.CompilerServices.RuntimeWrappedException>. When an assembly is created from C++ and non-C++ modules, and you want a **`catch`** block in C++ code to be invoked from its corresponding **`try`** clause when the **`try`** block throws a non-`System` exception, you must add the `[assembly:System::Runtime::CompilerServices::RuntimeCompatibility(WrapNonExceptionThrows=false)]` attribute to the source code for the non-C++ modules.

```cpp
// MSIL_linking.cpp
Expand All @@ -57,11 +59,9 @@ int main() {
*/
```

## Example
By changing the `Boolean` value of the `WrapNonExceptionThrows` attribute, you modify the ability of the C++ code to catch a non-`System` exception.

By changing the Boolean value of the `WrapNonExceptionThrows` attribute, you modify the ability of the Visual C++ code to catch a non-System exception.

```cpp
```csharp
// MSIL_linking_2.cs
// compile with: /target:module /addmodule:MSIL_linking.obj
// post-build command: link /LTCG MSIL_linking.obj MSIL_linking_2.netmodule /entry:MLinkTest.Main /out:MSIL_linking_2.exe /subsystem:console
Expand Down
2 changes: 1 addition & 1 deletion docs/cppcx/codesnippet/CPP/cppcx_strings/class1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ using namespace Strings;
//<snippet02>
using namespace Platform;
String^ str = L"hello";
void main(){}
int main(){}
//</snippet02>


Expand Down
2 changes: 2 additions & 0 deletions docs/docfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@
"windows/**.md": "cpp-windows"
},
"author": {
"index.md": "corob-msft",
"assembler/**.md": "corob-msft",
"attributes/**.md": "corob-msft",
"atl/**.md": "corob-msft",
Expand Down Expand Up @@ -176,6 +177,7 @@
"windows/**.md": "corob-msft"
},
"ms.author": {
"index.md": "corob",
"assembler/**.md": "corob",
"atl/**.md": "corob",
"atl-mfc-shared/**.md": "corob",
Expand Down
18 changes: 8 additions & 10 deletions docs/dotnet/how-to-specify-an-out-parameter.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
---
title: "How to: Specify an out Parameter"
title: "How to: Specify an out parameter"
ms.custom: "get-started-article"
ms.date: "11/04/2016"
helpviewer_keywords: ["function parameters", "out parameters"]
ms.assetid: 02862448-603c-4e9d-a5c5-b45fe38446e3
---
# How to: Specify an out Parameter
# How to: Specify an out parameter

This sample shows how to specify that a function parameter is an out parameter and how to call that function from a C# program.
This sample shows how to specify that a function parameter is an `out` parameter, and how to call that function from a C# program.

An out parameter is specified in Visual C++ with <xref:System.Runtime.InteropServices.OutAttribute> .
An `out` parameter is specified in C++ by using <xref:System.Runtime.InteropServices.OutAttribute> .

## Example

The first part of this sample is a Visual C++ DLL with a type that contains a function with an out parameter.
The first part of this sample creates a C++ DLL. It defines a type that contains a function with an `out` parameter.

```cpp
// cpp_out_param.cpp
// compile with: /LD /clr:safe
// compile with: /LD /clr
using namespace System;
public value struct TestStruct {
static void Test([Runtime::InteropServices::Out] String^ %s) {
Expand All @@ -26,11 +26,9 @@ public value struct TestStruct {
};
```

## Example

This is a C# client that consumes the Visual C++ component created in the previous example.
This source file is a C# client that consumes the C++ component created in the previous example.

```
```csharp
// cpp_out_param_2.cs
// compile with: /reference:cpp_out_param.dll
using System;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ A generic type was instantiated incorrectly. Check the type definition. For mo

The first sample uses C# to create a component that contains a generic type that has certain constraints that are not supported when authoring generic types in C++/CLR. For more information, see [Constraints on Type Parameters](/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters).

```cs
```csharp
// C3390.cs
// Compile by using: csc /target:library C3390.cs
// a C# program
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ A generic type was instantiated incorrectly. Check the type definition. For more

The following sample uses C# to create a component that contains a generic type that has certain constraints that are not supported when authoring generic types in C++/CLI. For more information, see [Constraints on Type Parameters](/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters).

```cs
```csharp
// C3391.cs
// Compile by using: csc /target:library C3391.cs
// a C# program
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ A generic type was instantiated incorrectly. Check the type definition. For more

The following sample uses C# to create a component that contains a generic type that has certain constraints that are not supported when authoring generic types in C++/CLI. For more information, see [Constraints on Type Parameters](/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters).

```cs
```csharp
// C3392.cs
// Compile by using: csc /target:library C3392.cs
// a C# program
Expand Down
2 changes: 1 addition & 1 deletion docs/extensions/consuming-generics-cpp-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ This example shows a generic class defined in C#.

### Code

```cs
```csharp
// consuming_generics_from_other_NET_languages.cs
// compile with: /target:library
// a C# program
Expand Down
4 changes: 2 additions & 2 deletions docs/extensions/identifier-cpp-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Compiler option: `/ZW`

In the following example, a class named **template** is created in C# and distributed as a DLL. In the C++/CLI program that uses the **template** class, the **__identifier** keyword conceals the fact that **template** is a standard C++ keyword.

```cs
```csharp
// identifier_template.cs
// compile with: /target:library
public class template {
Expand Down Expand Up @@ -66,7 +66,7 @@ Compiler option: `/clr`

In the following example, a class named **template** is created in C# and distributed as a DLL. In the C++/CLI program that uses the **template** class, the **__identifier** keyword conceals the fact that **template** is a standard C++ keyword.

```cs
```csharp
// identifier_template.cs
// compile with: /target:library
public class template {
Expand Down
2 changes: 1 addition & 1 deletion docs/extensions/literal-cpp-component-extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Notice the difference in the metadata for `sc` and `lit`: the `modopt` directive

The following sample, authored in C#, references the metadata created in the previous sample and shows the affect of **literal** and **static const** variables:

```cs
```csharp
// mcppv2_literal3.cs
// compile with: /reference:mcppv2_literal2.dll
// A C# program
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ The function `f` can be called from C# or Visual Basic, for example, as though i

In C#, an argument that is passed to a `ParamArray` parameter can be called by a variable number of arguments. The following code sample is in C#.

```cs
```csharp
// mcppv2_paramarray3.cs
// compile with: /r:mcppv2_paramarray2.dll
// a C# program
Expand Down