Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Использование c#-кода в с++-проекте  (Прочитано 10307 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« : 17-12-2009 10:58 » 

Жизнь продолжается, но уже в другом направлении.  Отлично
Есть тест-проект на c#. Теперь хотят сделать проект на с++, в котором было бы возможно вызывать уже готовые тесты из моего c#-проекта.
Ну а для этого надо их как-то поженить...  Скромно так...

Нашла вот такие статьи:

http://www.computerbase.de/forum/showthread.php?t=636766 (эта на немецком, но код читабелен Ага )
В ней идет ссылка на эту статью - уже на английском:
http://www.csharphelp.com/2006/5/c-classes-as-com-objects/

Сделала 2 учебных проекта (на c# - CsharpCode, на с++ - NativeCode).
Попыталась реализовать то, что написано. Имею:
1) с++-пример с немецкой страницы не компилируется вообще
2) пример с англоязычной страницы компилируется, но при попытке вызова CoCreateInstance() возвращает неутешительный результат "CoCreateInstance has not been called"...

Осталось по мелочам понять - и где же собака зарыта?  Здесь была моя ладья... А черт его знает... Не понял

Да, насчет c#-проекта:
- есть возможность либо каждому классу добавить парметр
[System.Runtime.InteropServices.ComVisible(true)]
- а можно в настройках проекта сказать "build -> register for com interop "

пробовала включать их по очереди и все вместе - на результат это не повлияло... Жаль

И еще - команды для создания tlb и регистрации длл-ли я написала в конце файла ManagedCode.cs.
Все это удобноо вызывать из старт->программы->microsoft .net framework sdk 2.0 -> sdk command prompt

Соответственно вопрос - может кто-то уже с этим сталкивался?
Уже самой интересно стало!

* example.rar (8.2 Кб - загружено 169 раз.)
Записан

холоднокровней, Маня, Ви не на работе
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #1 : 17-12-2009 11:46 » 

Ир, так я не понял, С++ нормальный требуется? Или всё-таки CLR?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #2 : 17-12-2009 12:58 » 

Джон,
хотят нормальный с++.

забыла дописать: среда обитания = студия 2005 + sp1
« Последнее редактирование: 17-12-2009 13:14 от Malaja » Записан

холоднокровней, Маня, Ви не на работе
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #3 : 17-12-2009 14:35 » 

Хотят как посложней? Ну-ну. Сорри. В смысле сочувствую.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 17-12-2009 14:41 » 

По-моему лучше написать внутри C++ проекта с включенной CLR native-обёртки для вызова решений из C#-сборки, а потом использовать эти обёртки из native-кода.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #5 : 17-12-2009 14:48 » 

Так, поборола я это дело.
Нашла еще один пример, он оказался наиболее применимым.

Подводные камни:
1) насколько я поняла, регистрировать надо не  только длл, но и tlb, т.е. достаточно одного вызова regasm.exe, но по такой схеме:
Код:
regasm.exe D:\...\csharp_code.dll /tlb:D:\..\csharp_code.tlb
2) я что-то напортачила с именами проекта и assemblies в AssemblyInfo.cs: я переименовала вручную assemblies (т.к. меняла название проекта) и это тоже оказалось неверно (я вместо имени проекта написала имя namespace, думая что это неважно).

3) в файле AssemblyInfo.cs должно стоять:
Код:
[assembly: ComVisible(true)]
по умолчание это значение = false

Итог - все работает.

///////////////////

Дим,
я так хотела с самого начала, но!
как я получу либ-файл у с#-ной длл???
Я способа не нашла...
Ну или подключать ее динамически через loadlibrary?

* example.rar (7.79 Кб - загружено 185 раз.)
« Последнее редактирование: 17-12-2009 14:55 от Malaja » Записан

холоднокровней, Маня, Ви не на работе
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 17-12-2009 15:03 » 

Malaja, у c#-dll не надо никаких lib-файлов. Нужно в свойствах проекта C++ указать сборку с CLR и подключить C#-dll обычным в .NET образом - через references.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #7 : 17-12-2009 15:23 » 

Дим,
а вид с++ проекта - "CLR class library" или самый обычный "class library"?
Записан

холоднокровней, Маня, Ви не на работе
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 17-12-2009 15:52 » 

Не могу сказать, я не пробовал собирать lib с CLR. dll или exe - тут понятно.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #9 : 17-12-2009 16:05 » 

поняла. попробую и расскажу Ага
Записан

холоднокровней, Маня, Ви не на работе
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #10 : 18-12-2009 14:13 » 

Дим,

создала обычный консольный проект на с++, к нему подключила проект на managed с++ как либ (его создала как clr class library).

При попытке компиляции выдает сообщение:
Код:
"error C3381: 'ManagedCode::ManagedCode' : assembly access specifiers are only available in code compiled with a /clr option"
А где включается эта опция???
Записан

холоднокровней, Маня, Ви не на работе
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #11 : 18-12-2009 14:26 » 

так, где выставить, я нашла:

properties -> general

Но теперь появились другие проблемы:
Код:
error LNK2028: unresolved token (0A000009) "public: __clrcall ManagedCode::ManagedCode::ManagedCode(void)" (??0ManagedCode@0@$$FQAM@XZ)
referenced in function "int __clrcall wmain(int,wchar_t * * const)"
(?wmain@@$$HYMHHQAPA_W@Z)
ManagedCode - класс из с++-managed - библиотеки.

И что бы это значило?

* without_interop.rar (11.16 Кб - загружено 152 раз.)
« Последнее редактирование: 18-12-2009 14:33 от Malaja » Записан

холоднокровней, Маня, Ви не на работе
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 18-12-2009 15:37 » 

Ну если CLR class library генерирует в качестве результата lib, а не dll, то этот lib нужно прописать в свойствах линкера, чтобы собралось. Либо через #pragma comment(lib, "<имя файла>")
« Последнее редактирование: 18-12-2009 15:39 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #13 : 18-12-2009 16:07 » 

в линкер я эту либу внесла, иначе класс был бы совсем неизвестен
Записан

холоднокровней, Маня, Ви не на работе
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #14 : 18-12-2009 20:01 » 

Открыл файлик посмотреть. Не, я не то имел в виду. Я имел в виду, что это будет такая lib, которую можно включить в native-приложение, которое собирается без CLR.

Поскольку меня самого этот вопрос в данный момент занимал, я сделал работающий пример для VS 2005.

В solution включены 3 проекта:
C# Class Library - в результате даёт dll, являющийся .NET assembly.
С++ CLR Class Library - в результате даёт lib, являющийся обычной lib для статической линковки внутри exe.
С++ Win32 Console Application - в результате даёт exe, являющийся обычным (не .NET) exe, хотя и использующим .NET для работы со сборкой.

Внутри .NET assembly реализован класс с методом.
Внутри C++ библиотеки реализован класс на C++, определённый в заголовочном файле, агрегирующий внутри себя экземпляр собственно обёртки. А обёртка агрегирует внутри себя экземпляр CLR-класса. Дополнительная внешняя обёртка сделана исключительно для того, чтобы из заголовочного файла убрать все ссылки на CLR-элементы, и чтобы пользующиеся этим заголовочным файлом приложения не нуждались бы в подключении CLR.
Внутри C++ приложения используется native-обёртка.

Подключения заголовочных файлов и линковка библиотеки находятся в stdafx.h.

На мой взгляд такое кодирование хотя и аккуратное, зато муторное и тяжёлое для сопровождения изменений в .NET-сборке, а в обёртках (что у меня не сделано) нужно ещё не забывать определять конструкторы копирования.

* CLRLibInNativeApp.zip (12.24 Кб - загружено 195 раз.)
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #15 : 21-12-2009 12:15 » 

Дим,
спасибочки за пример!
К сожалению, на выходных у меня дома неожиданно умер интернет, поэтому увидела решение только сегодня на работе. Сейчас разбираюсь и сравниваю, что у меня было не так.
Насчет native-проекта: я его сначала сделала не связанным с CLR, но он не компилировался, поейтому включила опцию /clr. Потом у тебя увидела, что надо было включить clr-проверку...

Сравнив оба решения, я постепенноприхожу к выводу, что использование com-а выглядит немного проще, хотя и ненамного... В любом случае достаточно геморройно все это...

еще раз огромное спасибо за помощь!
Записан

холоднокровней, Маня, Ви не на работе
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #16 : 21-12-2009 13:16 » 

Так, мелкие дополнения для тех, кому, не дай бог, придется с ейтим разбираться Ага
 
Определила следующее:
1) в managed-коде:
    - вместо <public ref class> достаточноо просто нормальное определение <class>
    -  про gcroot просто не знала (стыдно, но я себя успокоила тем, что учиться никогда не поздно Ага )
    - дополнительная внешняя обертка просто необходима (я до этого не додумалась, пыталась все решить дефайнами)
2) в native-коде:
   - вместо <properties -> configuration properties -> general ->  common language runtime  support  = yes> надо использовать <properties -> c/c++ -> code generation -> basic runtime checks = both>
   - если все 3 проекта существуют автономно (т.е. не соединены, как у тебя, в одно целое), то необходимо для native-проекта внести нашу c#-длл как reference, при этом включить <copy local>, <copy dependencies> и <copy local satellite>, выключить же <use dependencies in build> и <use in build>.
Если не внести этот референц, то длл просто не находится...
Записан

холоднокровней, Маня, Ви не на работе
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 21-12-2009 13:32 » 

Хм... Я такие properties не исправлял, они у меня остались со значениями по умолчанию.

А про gcroot я тоже не знал, пока не получил ошибку, что managed переменные нельзя объявлять в unmanaged контексте Ага
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #18 : 21-12-2009 15:16 » 

Понятно Ага
насчет свойств - я сначала сделала обычный c++-проект (как ехе), но онне компилировался и требовал поддержки CLR, поэтому я изменила установки, в результате чего у меня получился опять CLR-поддерживающий проект, хотя я этого и не хотела.
А потом увидела у тебя, как можно обойти такую проблему.

Я уже тихо думаю - может стоит это оформить статьей? Или это слишком специфично и никому не понадобится?
Записан

холоднокровней, Маня, Ви не на работе
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #19 : 22-12-2009 12:28 » 

О статье: мне не нравятся двойные обёртки. Хотел бы увидеть более элегантное решение, требующее меньше трудозатрат на "тупое" кодирование.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #20 : 22-12-2009 12:49 » 

Мне они тоже не нравятся, но и другого решения я не находила...
Записан

холоднокровней, Маня, Ви не на работе
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines