C ++成员变量未初始化

时间:2020-07-13 19:48:43

标签: c# c++

我的任务是为.NET应用程序提供C ++代码库。 C ++代码在生产中已经使用了几年,并且可以正常运行。

我将C ++代码打包到一个dll中,并构建了一个基于C的API,以使其通过P / Invoke可用于.NET。

如果我通过基于C的测试应用程序测试API,那么一切都会按预期进行。如果我从C#应用程序测试API,则该应用程序将挂起。在调试过程中,我发现尽管执行了用于初始化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;
};

在导出的C方法中,这样声明了Product类型的变量:

void ProcessProduct(Type1* c1, Type2* c2)
{
    //
    // Do stuff
    //
    Product<Factory> p1(f1);
    //
    // Do stuff
    //
}

执行了上面的行后,p1中的状态成员变量仍未初始化。仅当从.NET调用API时才发生这种情况,如果从C测试应用程序调用了API,则一切都将按预期方式初始化。

ProcessProduct方法在C#中这样声明:

    [DllImport("product.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern void ProcessProduct(IntPtr c1, IntPtr c2);

我的C ++知识是基础知识,因此我不确定自己缺少什么。我在Windows 10上使用Visual Studio 2019(16.6.3)。问题出现在Debug x86中,我没有在x64上对其进行测试。

2 个答案:

答案 0 :(得分:1)

我终于设法找出问题并解决。

正如我所说的那样,C ++代码库已经稳定了几年,并且已经可以在生产环境中正常运行,因此我没有理由对其进行修改。

开发基于C的API之后,我使用C应用程序对其进行了测试,并且效果很好。之后,我开始使用C#应用程序,API开始崩溃或挂起。这让我感到困惑,因为API是通过C应用程序运行的,而不是通过C#运行的。事实是,在我开始处理C#部分之后,我没有再次测试C应用程序。
出现问题是因为我添加了“ pragma pack”指令以将某些结构从C映射到C#。我没有将其仅添加到这些结构中,而是将其添加到了一个包含在其他头文件之前的头文件中,并且该pragma指令弄乱了C ++代码库。说实话,Visual Studio生成了一些有关实用程序包不一致的警告,但我最初忽略了它们。

答案 1 :(得分:0)

某些样式可能无法解决问题,首先将product_status放在模板之外(其不依赖于T),第二个“类枚举”可能会消除歧义alpha(因此我无法分辨,bul可能存在其他称为alpha的东西在代码中的某处)

您可以“删除”复制构造函数和赋值运算符。

您可能正在创建一个称为“处理程序类”的东西,如果是这种情况,则如果该类是“产品”,则应从工厂函数中返回它,而不要指向该函数。尝试发现您是否可以使用shered_ptr或unique_ptr代替“ Product”

https://godbolt.org/z/55c9TW