Мне было поручено сделать доступной базу кода C ++ для приложения. NET. Код C ++ используется в производственной среде в течение нескольких лет и работает без проблем.
Я упаковал код C ++ в dll и построил API на основе C, чтобы сделать его доступным для. NET через P /Invoke.
Если я тестирую API с помощью тестового приложения на основе C, все работает, как ожидалось. Если я тестирую API из приложения C#, приложение зависает. Во время отладки я обнаружил, что переменная-член C ++ просто не инициализируется, хотя код для ее инициализации выполняется.
Класс C ++ выглядит примерно так:
template<class T> class Product
{
enum product_status
{
alpha,
beta,
production
};
public:
explicit Product(T& src) : source(&src), status(alpha) { }
void bind(T& src) { source = &src; }
void reset()
{
source->reset();
status = alpha;
}
private:
Product(const Product<T>&);
const Product<T>& operator = (const Product<T>&);
T* source;
product_status status;
};
Переменная типа Product объявляется в экспортированном методе C следующим образом:
void ProcessProduct(Type1* c1, Type2* c2)
{
//
// Do stuff
//
Product<Factory> p1(f1);
//
// Do stuff
//
}
После выполнения строки выше переменная-член состояния в p1 все еще не инициализирована. Это происходит, только если API вызывается из. NET, если API вызывается из C тестового приложения, все инициализируется должным образом.
Метод ProcessProduct объявлен в C# следующим образом:
[DllImport("product.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void ProcessProduct(IntPtr c1, IntPtr c2);
Мои знания C ++ базовые c, поэтому я не уверен, что мне не хватает. Я использую Visual Studio 2019 (16.6.3) на Windows 10. Проблема появляется в Debug x86, мне не нужно тестировать ее на x64.