У меня есть следующая структура в MFC DLL:
struct retornoSAP
{
enum tipoRetorno
{
Ok,
Falha,
AbrirArquivo, // mStrData válido
InserirArquivo, // mStrData válido
retornoMap, // mLstData válido
retornoTable, // mLstTable válido
retornoString, // mStrData válido
};
tipoRetorno mTipo;
CString mStrData;
CMapStringToString mLstData;
retTable* mLstTable;
CMapStringToString mLstVars;
retornoSAP( tipoRetorno pTipo )
{
mTipo = pTipo;
mLstTable = NULL;
}
~retornoSAP()
{
if ( mLstTable ) CISap::release( mLstTable );
}
};
Определение retTable:
typedef vector<CMapStringToString*> retTable;
Эта структура используется для хранения данных, считываемых из SAP API, и у меня есть много функций, которые возвращают значение "retornoSAP".
Случается, что я должен вызывать эти функции из VB.NET, используя P/Invoke (DllImport). Я прочитал некоторые материалы о маршалинге неуправляемых типов.NET (например, http://blogs.msdn.com/b/dsvc/archive/2009/02/18/marshalling-complicated-structures-using-pinvoke.aspx), и, вероятно, было бы легко объединить структуру с некоторыми базовыми типами в ней, но я задаюсь вопросом, возможно ли даже маршалить CMapStringToString или, что еще хуже, вектор CMapStringToString.
Мой вопрос в том, стоит ли потратить некоторое время на то, чтобы перевести эту структуру на тип.NET (в этом случае, где я мог бы найти хорошую документацию)?
Если это не так, мне кажется, что это хорошая идея использовать синтаксический анализатор XML в C++, записать все мои данные в структуру XML и затем вернуть эту структуру XML как строку BSTR, чтобы я мог прочитать возвращаемое значение BSTR легко это в моем приложении.NET и проанализировать его обратно в структуру XML. В этом случае я бы передал некоторые большие строки между MFC DLL и.NET-приложением...
Вы не можете справиться с классами MFC с помощью P/INVOKE. Я думаю, вы можете выбрать один из двух вариантов:
ref classes
в мир .NET
и вызывать из его методов DLL MFC. Изнутри класса ref вы можете прочитать свои исходные структуры MFC и заполнить некоторые другие структуры, более дружественные.NET.extern "C"
, чтобы избежать манипуляции с именем и преобразовать внутреннюю структуру в нечто более легкое в управлении, строка, как вы предполагаете, будет не очень элегантным, но самым передовым решением; )В обоих решениях есть некоторые издержки по производительности, но я предполагаю, что первый будет платить лучше, и иногда это единственное, что предотвращает модификацию исходной библиотеки MFC, и иногда это возможно. Второй вариант, вероятно, проще, но передача магической строки потребует некоторого разбора, приводящего к утечке производительности, возможных ошибок, поэтому вам нужно больше тестов, больше затрат и так далее.
Другим недостатком решения 1 является необходимость дополнительного развертывания для C++/CLI-перераспределителей.
Я не упоминал, так как вы, вероятно, уже знаете, но для выполнения такого взаимодействия требуется код.NET, скомпилированный в режиме x86, если скомпилированная dll C++ 32 бит.