Я хочу импортировать неуправляемую DLL C++ и вызвать функцию, которая принимает stringstream
в качестве параметра. В C# нет класса stringstream
, так может ли кто-нибудь сказать мне, как вызвать такую функцию из программы C#?Как я могу вызвать функцию C++ DLL, которая принимает параметр string stringstream из C#?
ответ
Если вы можете изменить dll C++, экспортируйте версию простой строки. В противном случае вам нужно создать управляемый проект оболочки C++, импортировать другую C++ dll, экспортировать его как управляемую функцию и вызвать это из вашего кода на C#. C++ interop действительно отстой.
Я боюсь, что вам нужно будет создать свой собственный класс StringStream
в C#, чтобы иметь возможность использовать функции, экспортированные из этой DLL. Как вы упомянули, .NET Framework не предоставляет какой-либо подобный класс из коробки.
Самый простой способ - это, вероятно, обернуть класс StringBuilder
, предоставляемый платформой .NET Framework, чтобы он мог функционировать как поток. См. this blog post для дальнейшего объяснения и некоторого примера кода.
Аналогичный вопрос также был дан в MSDN Magazine: http://msdn.microsoft.com/en-us/magazine/cc163768.aspx. Вы можете найти некоторые из намеков и/или пример кода, который там будет полезен.
Вы не должны раскрывать шаблонные объекты через DLL, период.
Плавающие объекты (например, почти все в std::
) становятся вставками. Таким образом, ваша DLL получает свою собственную частную копию реализации. Модуль, вызывающий вашу DLL, также получит свою собственную частную реализацию stringstream
. Прохождение между ними означает, что вы непреднамеренно соткаете две несвязанные реализации вместе. Для многих проектов, если вы используете одни и те же настройки сборки, это, вероятно, не проблема.
Но даже если вы используете один и тот же компилятор и смешиваете выпускую DLL с отладчиком EXE, вы обнаружите повреждение кучи/кучи и другие сложные проблемы.
И это только использование вашей DLL из другой неуправляемой версии C++ exe/dll. Пересечение тогда линий в .NET еще более проблематично.
Решение должно изменить интерфейс вашей DLL на то, что играет дружеские границы DLL. Или COM (вы можете использовать, например, IStream
), или просто интерфейс C-стиля, такой как winapi.
Вы пытаетесь связать собственный код C++ с управляемым кодом на C#. Лучший способ сделать это в целом - ввести средний уровень в управляемом C++, который обеспечит интерфейс для вызовов с C#.
Создайте dll dll оболочки в c или C++, который предоставляет дружественный вызов этой функции. Это лучший способ.
например
BOOL getString(TCHAR * myreturnString, DWORD *size);
Я пытался импортировать функцию в неуправляемом C++, которая принимает зЬй: строку в качестве параметра в C# программы и получил следующую ошибку во время выполнения: «Необработанное исключение: System.AccessViolationException: Пытались читать или писать защищенную память.Это часто указывает на то, что другая память повреждена. В Win32API.processRequestWithStream (String & inputString, String & outputString) в Win32API.Main() "- Какая может быть причина для этой ошибки? – user186246
'std :: string' является' typedef' из 'std :: basic_string', т. Е. Это так же шаблон, как 'stringstream'. –
А как насчет различных умных указателей?Если я беру это буквально, это означает, что не следует выделять нетривиальные C++ для границ DLL. –