2010-12-27 3 views
8

Я хочу импортировать неуправляемую DLL C++ и вызвать функцию, которая принимает stringstream в качестве параметра. В C# нет класса stringstream, так может ли кто-нибудь сказать мне, как вызвать такую ​​функцию из программы C#?Как я могу вызвать функцию C++ DLL, которая принимает параметр string stringstream из C#?

ответ

3

Если вы можете изменить dll C++, экспортируйте версию простой строки. В противном случае вам нужно создать управляемый проект оболочки C++, импортировать другую C++ dll, экспортировать его как управляемую функцию и вызвать это из вашего кода на C#. C++ interop действительно отстой.

3

Я боюсь, что вам нужно будет создать свой собственный класс StringStream в C#, чтобы иметь возможность использовать функции, экспортированные из этой DLL. Как вы упомянули, .NET Framework не предоставляет какой-либо подобный класс из коробки.

Самый простой способ - это, вероятно, обернуть класс StringBuilder, предоставляемый платформой .NET Framework, чтобы он мог функционировать как поток. См. this blog post для дальнейшего объяснения и некоторого примера кода.

Аналогичный вопрос также был дан в MSDN Magazine: http://msdn.microsoft.com/en-us/magazine/cc163768.aspx. Вы можете найти некоторые из намеков и/или пример кода, который там будет полезен.

11

Вы не должны раскрывать шаблонные объекты через DLL, период.

Плавающие объекты (например, почти все в std::) становятся вставками. Таким образом, ваша DLL получает свою собственную частную копию реализации. Модуль, вызывающий вашу DLL, также получит свою собственную частную реализацию stringstream. Прохождение между ними означает, что вы непреднамеренно соткаете две несвязанные реализации вместе. Для многих проектов, если вы используете одни и те же настройки сборки, это, вероятно, не проблема.

Но даже если вы используете один и тот же компилятор и смешиваете выпускую DLL с отладчиком EXE, вы обнаружите повреждение кучи/кучи и другие сложные проблемы.

И это только использование вашей DLL из другой неуправляемой версии C++ exe/dll. Пересечение тогда линий в .NET еще более проблематично.

Решение должно изменить интерфейс вашей DLL на то, что играет дружеские границы DLL. Или COM (вы можете использовать, например, IStream), или просто интерфейс C-стиля, такой как winapi.

+0

Я пытался импортировать функцию в неуправляемом C++, которая принимает зЬй: строку в качестве параметра в C# программы и получил следующую ошибку во время выполнения: «Необработанное исключение: System.AccessViolationException: Пытались читать или писать защищенную память.Это часто указывает на то, что другая память повреждена. В Win32API.processRequestWithStream (String & inputString, String & outputString) в Win32API.Main() "- Какая может быть причина для этой ошибки? – user186246

+1

'std :: string' является' typedef' из 'std :: basic_string ', т. Е. Это так же шаблон, как 'stringstream'. –

+1

А как насчет различных умных указателей?Если я беру это буквально, это означает, что не следует выделять нетривиальные C++ для границ DLL. –

0

Вы пытаетесь связать собственный код C++ с управляемым кодом на C#. Лучший способ сделать это в целом - ввести средний уровень в управляемом C++, который обеспечит интерфейс для вызовов с C#.

0

Создайте dll dll оболочки в c или C++, который предоставляет дружественный вызов этой функции. Это лучший способ.

например

BOOL getString(TCHAR * myreturnString, DWORD *size);