diff --git a/.github/workflows/example-test.yaml b/.github/workflows/example-test.yaml index 2a4bfd86..73665ce6 100644 --- a/.github/workflows/example-test.yaml +++ b/.github/workflows/example-test.yaml @@ -14,6 +14,8 @@ jobs: path: outproc - name: 32 Bit path: 32bit + - name: C++/CLI + path: cppcli steps: - uses: actions/checkout@v3 @@ -37,6 +39,8 @@ jobs: - name: Build run: dotnet build -c Release + - uses: ilammy/msvc-dev-cmd@v1 + - name: Run ${{ matrix.test_suite.Name }} Acceptance test run: .\msbuild-acceptance-test.cmd working-directory: .\examples\${{ matrix.test_suite.path }}\scripts diff --git a/README.md b/README.md index de39e52d..1ba185e1 100644 --- a/README.md +++ b/README.md @@ -376,6 +376,9 @@ Depending on whether you want to process 32bit or 64bit assemblies, you need to > To prevent this it is **recommended that the assembly is compiled as a 32 bit assembly** and not as an AnyCPU assembly. > see: +> Warning! +> In order to use 32 bit support with the build targets, the x86 version of .NET must be installed, as dscom requests the hostfxr.dll to be loaded. + ## Migration notes (mscorelib vs System.Private.CoreLib) Both assemblies are **ComVisible=false** but lot of .NET Framework types are **ComVisible=true**. diff --git a/examples/32bit/scripts/msbuild-acceptance-test.cmd b/examples/32bit/scripts/msbuild-acceptance-test.cmd index 7dc5ec9e..5b707cca 100644 --- a/examples/32bit/scripts/msbuild-acceptance-test.cmd +++ b/examples/32bit/scripts/msbuild-acceptance-test.cmd @@ -10,6 +10,8 @@ dotnet pack src\dscom.build\dscom.build.csproj -p:Configuration=Release IF NOT EXIST %root%\_packages MKDIR _packages +XCOPY /Y /I /C /F .\src\dscom\bin\x64\Release\*.nupkg _packages\ +XCOPY /Y /I /C /F .\src\dscom.build\bin\x64\Release\*.nupkg _packages\ XCOPY /Y /I /C /F .\src\dscom\bin\Release\*.nupkg _packages\ XCOPY /Y /I /C /F .\src\dscom.build\bin\Release\*.nupkg _packages\ diff --git a/examples/cppcli/CppCli.sln b/examples/cppcli/CppCli.sln new file mode 100644 index 00000000..2385b338 --- /dev/null +++ b/examples/cppcli/CppCli.sln @@ -0,0 +1,48 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35506.116 d17.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CppLibrary", "CppLibrary\CppLibrary.vcxproj", "{4E2EE544-4FD0-4790-A6D7-D6A75F84F902}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsLibrary", "CsLibrary\CsLibrary.csproj", "{87C7349D-418E-47D7-9BBC-C995D008F333}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4E2EE544-4FD0-4790-A6D7-D6A75F84F902}.Debug|Any CPU.ActiveCfg = Debug|x64 + {4E2EE544-4FD0-4790-A6D7-D6A75F84F902}.Debug|Any CPU.Build.0 = Debug|x64 + {4E2EE544-4FD0-4790-A6D7-D6A75F84F902}.Debug|x64.ActiveCfg = Debug|x64 + {4E2EE544-4FD0-4790-A6D7-D6A75F84F902}.Debug|x64.Build.0 = Debug|x64 + {4E2EE544-4FD0-4790-A6D7-D6A75F84F902}.Debug|x86.ActiveCfg = Debug|Win32 + {4E2EE544-4FD0-4790-A6D7-D6A75F84F902}.Debug|x86.Build.0 = Debug|Win32 + {4E2EE544-4FD0-4790-A6D7-D6A75F84F902}.Release|Any CPU.ActiveCfg = Release|x64 + {4E2EE544-4FD0-4790-A6D7-D6A75F84F902}.Release|Any CPU.Build.0 = Release|x64 + {4E2EE544-4FD0-4790-A6D7-D6A75F84F902}.Release|x64.ActiveCfg = Release|x64 + {4E2EE544-4FD0-4790-A6D7-D6A75F84F902}.Release|x64.Build.0 = Release|x64 + {4E2EE544-4FD0-4790-A6D7-D6A75F84F902}.Release|x86.ActiveCfg = Release|Win32 + {4E2EE544-4FD0-4790-A6D7-D6A75F84F902}.Release|x86.Build.0 = Release|Win32 + {87C7349D-418E-47D7-9BBC-C995D008F333}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {87C7349D-418E-47D7-9BBC-C995D008F333}.Debug|Any CPU.Build.0 = Debug|Any CPU + {87C7349D-418E-47D7-9BBC-C995D008F333}.Debug|x64.ActiveCfg = Debug|Any CPU + {87C7349D-418E-47D7-9BBC-C995D008F333}.Debug|x64.Build.0 = Debug|Any CPU + {87C7349D-418E-47D7-9BBC-C995D008F333}.Debug|x86.ActiveCfg = Debug|Any CPU + {87C7349D-418E-47D7-9BBC-C995D008F333}.Debug|x86.Build.0 = Debug|Any CPU + {87C7349D-418E-47D7-9BBC-C995D008F333}.Release|Any CPU.ActiveCfg = Release|Any CPU + {87C7349D-418E-47D7-9BBC-C995D008F333}.Release|Any CPU.Build.0 = Release|Any CPU + {87C7349D-418E-47D7-9BBC-C995D008F333}.Release|x64.ActiveCfg = Release|Any CPU + {87C7349D-418E-47D7-9BBC-C995D008F333}.Release|x64.Build.0 = Release|Any CPU + {87C7349D-418E-47D7-9BBC-C995D008F333}.Release|x86.ActiveCfg = Release|Any CPU + {87C7349D-418E-47D7-9BBC-C995D008F333}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/examples/cppcli/CppLibrary/CppLibrary.vcxproj b/examples/cppcli/CppLibrary/CppLibrary.vcxproj new file mode 100644 index 00000000..dddfb8a7 --- /dev/null +++ b/examples/cppcli/CppLibrary/CppLibrary.vcxproj @@ -0,0 +1,123 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + true + {4E2EE544-4FD0-4790-A6D7-D6A75F84F902} + NetCoreCProj + CppLibrary + 10.0 + net8.0 + + + + DynamicLibrary + true + v143 + NetCore + Unicode + + + DynamicLibrary + false + v143 + NetCore + Unicode + + + DynamicLibrary + true + v143 + NetCore + Unicode + + + DynamicLibrary + false + v143 + NetCore + Unicode + + + + + + + + + + + + + + + + + + + + + + + Level3 + _DEBUG;%(PreprocessorDefinitions) + + + + + + + + Level3 + WIN32;_DEBUG;%(PreprocessorDefinitions) + + + + + + + + Level3 + WIN32;NDEBUG;%(PreprocessorDefinitions) + + + + + + + + Level3 + NDEBUG;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/cppcli/CppLibrary/CppLibrary.vcxproj.filters b/examples/cppcli/CppLibrary/CppLibrary.vcxproj.filters new file mode 100644 index 00000000..1e46703f --- /dev/null +++ b/examples/cppcli/CppLibrary/CppLibrary.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + + + Source Files + + + \ No newline at end of file diff --git a/examples/cppcli/CppLibrary/MyCppClass.cpp b/examples/cppcli/CppLibrary/MyCppClass.cpp new file mode 100644 index 00000000..6300f70b --- /dev/null +++ b/examples/cppcli/CppLibrary/MyCppClass.cpp @@ -0,0 +1,7 @@ +#include "MyCppClass.h" +namespace CppNs { + int MyCppClass::Add(int a, int b) + { + return a + b; + } +} \ No newline at end of file diff --git a/examples/cppcli/CppLibrary/MyCppClass.h b/examples/cppcli/CppLibrary/MyCppClass.h new file mode 100644 index 00000000..4baee416 --- /dev/null +++ b/examples/cppcli/CppLibrary/MyCppClass.h @@ -0,0 +1,8 @@ +#pragma once +namespace CppNs { + public ref class MyCppClass + { + public: + int Add(int a, int b); + }; +} \ No newline at end of file diff --git a/examples/cppcli/CppLibrary/packages.config b/examples/cppcli/CppLibrary/packages.config new file mode 100644 index 00000000..e2887c72 --- /dev/null +++ b/examples/cppcli/CppLibrary/packages.config @@ -0,0 +1,2 @@ + + diff --git a/examples/cppcli/CsLibrary/CsLibrary.csproj b/examples/cppcli/CsLibrary/CsLibrary.csproj new file mode 100644 index 00000000..a6fcbcf3 --- /dev/null +++ b/examples/cppcli/CsLibrary/CsLibrary.csproj @@ -0,0 +1,15 @@ + + + + net8.0-windows + enable + enable + True + x64 + + + + + + + diff --git a/examples/cppcli/CsLibrary/MyCsClass.cs b/examples/cppcli/CsLibrary/MyCsClass.cs new file mode 100644 index 00000000..ea956005 --- /dev/null +++ b/examples/cppcli/CsLibrary/MyCsClass.cs @@ -0,0 +1,19 @@ +using System.Runtime.InteropServices; + +namespace CsNs +{ + [ComVisible(true)] + [Guid("4468308A-1E42-4CE2-8BC0-4F6AFA1951E0")] + [InterfaceType(ComInterfaceType.InterfaceIsDual)] + public interface IComClass + { + int Add(int a, int b); + }; + + [ComVisible(true)] + [ClassInterface(ClassInterfaceType.None)] + [Guid("6610DBEC-DD26-416B-BF94-A5D0C7192F6C")] + public class MyCsClass : CppNs.MyCppClass, IComClass + { + } +} diff --git a/examples/cppcli/scripts/msbuild-acceptance-test.cmd b/examples/cppcli/scripts/msbuild-acceptance-test.cmd new file mode 100644 index 00000000..e8126ed3 --- /dev/null +++ b/examples/cppcli/scripts/msbuild-acceptance-test.cmd @@ -0,0 +1,75 @@ +@ECHO off + +REM Run this script from VsDevCmd + +SET root=%~dp0\..\..\..\ + +PUSHD %root% +dotnet build-server shutdown + +dotnet pack src\dscom.build\dscom.build.csproj -p:Configuration=Release + +IF NOT EXIST %root%\_packages MKDIR _packages + +XCOPY /Y /I /C /F .\src\dscom\bin\x64\Release\*.nupkg _packages\ +XCOPY /Y /I /C /F .\src\dscom.build\bin\x64\Release\*.nupkg _packages\ +XCOPY /Y /I /C /F .\src\dscom\bin\Release\*.nupkg _packages\ +XCOPY /Y /I /C /F .\src\dscom.build\bin\Release\*.nupkg _packages\ + +dotnet build-server shutdown + +dotnet nuget locals global-packages --clear + +POPD + +PUSHD %~dp0\..\CppLibrary + +msbuild -nodeReuse:False -t:Clean -p:Configuration=Release -p:PerformAcceptanceTest=Runtime +nuget restore -SolutionDirectory .. + +POPD + +PUSHD %~dp0\..\CsLibrary + +msbuild -nodeReuse:False -t:Clean -p:Configuration=Release -p:PerformAcceptanceTest=Runtime -p:SkipResolvePackageAssets=true + +dotnet build-server shutdown + +dotnet add CsLibrary.csproj package --prerelease -s %root%\_packages dSPACE.Runtime.InteropServices.BuildTasks + +dotnet build-server shutdown + +msbuild -nodeReuse:False -t:Restore -p:Configuration=Release -p:Platform=x64 -p:TargetPlatform=net8.0-windows -p:PerformAcceptanceTest=Runtime -p:SkipResolvePackageAssets=true + +dotnet build-server shutdown + +msbuild -nodeReuse:False -t:Build -p:Configuration=Release -p:Platform=x64 -p:TargetPlatform=net8.0-windows -p:PerformAcceptanceTest=Runtime -bl:%~dp0\net80x86.binlog +SET ERRUNTIMEX64_NET80=%ERRORLEVEL% + +msbuild -nodeReuse:False -t:Clean -p:Configuration=Release -p:Platform=x64 -p:TargetPlatform=net8.0-windows -p:PerformAcceptanceTest=Runtime ..\CppLibrary\CppLibrary.vcxproj + +dotnet build-server shutdown + +dotnet remove CsLibrary.csproj package dSPACE.Runtime.InteropServices.BuildTasks + +POPD + +SetLocal EnableDelayedExpansion + +SET EXITCODE=0 + +IF NOT "%ERRUNTIMEX64_NET80%" == "0" ( + SET EXITCODE=1 + ECHO "::warning::Runtime specific acceptance test for platform x64 using .NET 8.0 failed." +) + +IF NOT EXIST %~dp0\..\CsLibrary\bin\x64\Release\net8.0-windows\CsLibrary.tlb ( + ::SET EXITCODE=1 + ECHO "::warning::Could not find exported TLB file for .NET 8 (x64)" +) + +IF "%EXITCODE%" == "0" ( + ECHO "Acceptance test completed successfully." +) + +EXIT /B %EXITCODE% diff --git a/examples/outproc/scripts/msbuild-acceptance-test.cmd b/examples/outproc/scripts/msbuild-acceptance-test.cmd index 04fafd63..af057802 100644 --- a/examples/outproc/scripts/msbuild-acceptance-test.cmd +++ b/examples/outproc/scripts/msbuild-acceptance-test.cmd @@ -10,6 +10,8 @@ dotnet pack -p:Configuration=Release IF NOT EXIST %root%\_packages MKDIR _packages +XCOPY /Y /I /C /F .\src\dscom\bin\x64\Release\*.nupkg _packages\ +XCOPY /Y /I /C /F .\src\dscom.build\bin\x64\Release\*.nupkg _packages\ XCOPY /Y /I /C /F .\src\dscom\bin\Release\*.nupkg _packages\ XCOPY /Y /I /C /F .\src\dscom.build\bin\Release\*.nupkg _packages\