У меня есть решение VS2008, связанное с проектом, который генерирует исполняемый файл C #, который ссылается на проект, который генерирует dll, содержащую как C ++ / CLI, так и неуправляемый C ++.
Я хотел бы объединить их в один исполняемый файл, поскольку DLL C ++ содержит код безопасности, который я хочу встроить в основной исполняемый файл.
Я не могу использовать ILMerge, так как DLL содержит как управляемый, так и неуправляемый код. Предлагаемое решение, по-видимому, заключается в использовании link.exe для связи сборки C # с объектными файлами C ++. Это то, что я пытаюсь сделать.
Я вручную отредактировал файл проекта для исполняемого файла c #, чтобы сгенерировать сетевой модуль. Я добавил шаг после сборки в исполняемый проект, чтобы запустить link.exe, чтобы связать сетевой модуль c # и скомпилированные объектные файлы C ++, а затем запустить mt.exe, чтобы объединить манифесты сборки, созданные обоими проектами. Это выполняется успешно, но исполняемый файл все еще содержит ссылку и использует типы c ++, определенные в dll, сгенерированные обычным процессом сборки для проекта C ++.
Затем я указал / NOASSEMBLY в настройках проекта для DLL C ++, поэтому он также генерирует сетевой модуль. В проекте C # я удалил ссылку на проект C ++, но добавил зависимость проекта в решение. Я вручную отредактировал файл проекта C #, добавив в него:
<ItemGroup>
<AddModules Include="..\Debug\librarycode.netmodule" />
</ItemGroup>
т.е. для ссылки на сетевой модуль C ++, который теперь генерируется проектом C ++.
Однако теперь шаг компоновщика в моем событии пост-сборки завершается с помощью:
error LNK2027: unresolved module reference 'librarycode.netmodule'
fatal error LNK1311: 1 unresolved module references:
Это вполне понятно, так как я не делаю ссылки в сетевом модуле библиотечного кода; Я ссылаюсь на объектные файлы C ++, используемые для генерации сетевого модуля.
Короче говоря, как объединить исполняемый файл c # и объектные файлы C ++ в одну сборку? Что я пропустил?
До сих пор моим источником информации (кроме ссылки на команду link.exe и т. Д. В MSDN) являются две следующие статьи:
Заранее большое спасибо.
Update1
Я точно следовал примеру в блоге Стива Тейшейры и убедился, что он работает. Используя рефлектор, я вижу, что полученный исполняемый файл содержит два сетевых модуля. Сетевой модуль c # содержит ссылку на другой сетевой модуль, но без имени ?! Если вы переместите сборку в новый каталог, второй сетевой модуль становится не связанным (очевидно), но исполняемый файл по-прежнему будет работать, так как в сетевом модуле c # существуют типы с правильным определением.
Обратите внимание, что оригинальный сетевой модуль c # содержит именованную ссылку на сетевой модуль c ++, поэтому это должен быть шаг компоновщика, который удаляет имя.
Пытаясь следовать этому примеру в моем примере проекта, я добавил аргумент / ASSEMBLYMODULE к моему шагу компоновщика после сборки. Компоновщик теперь не работает с
LNK2022: metadata operation failed (80040427) : Public type 'MixedLanguageLibrary.Class1' is defined in multiple places in this assembly: 'MixedLanguageDemo.exe' and 'mixedlanguagelibrary.netmodule'
LINK : fatal error LNK1255: link failed because of metadata errors
Я думаю, что это магия компоновщика, которая удаляет ссылочное имя модуля, которое я пропускаю.
Любые идеи приветствуются.
Update2
Я сократил свой проект до максимально простого и пытаюсь скомпилировать его из командной строки. Следующий пакетный файл успешно создает пример в блоге Стива Тейшейры:
setlocal
call "C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"
if errorlevel 1 goto End
cl /c /MD nativecode.cpp
if errorlevel 1 goto End
cl /clr /LN /MD clrcode.cpp nativecode.obj
if errorlevel 1 goto End
csc /target:module /addmodule:clrcode.netmodule Program.cs
if errorlevel 1 goto End
link /LTCG /CLRIMAGETYPE:IJW /ENTRY:ConsoleApplication1.Program.Main /SUBSYSTEM:CONSOLE /ASSEMBLYMODULE:clrcode.netmodule /OUT:MixedApp.exe clrcode.obj nativecode.obj program.netmodule
:End
Следующий пакетный файл не может создать мой пример кода с ошибкой компоновщика LNK2022:
setlocal
call "C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"
if errorlevel 1 goto End
cl /c /MD messageprovider.cpp
if errorlevel 1 goto End
cl /clr /LN /MD managedmessageprovider.cpp messageprovider.obj
if errorlevel 1 goto End
csc /target:module /addmodule:managedmessageprovider.netmodule Program.cs Form1.cs Form1.Designer.cs
if errorlevel 1 goto End
link /LTCG /CLRIMAGETYPE:IJW /ENTRY:MixedLanguageDemo.Program.Main /SUBSYSTEM:WINDOWS /ASSEMBLYMODULE:managedmessageprovider.netmodule /OUT:MixedLanguageDemo.exe managedmessageprovider.obj messageprovider.obj program.netmodule
:End
Время для определения разницы: - (