2013-05-10 74 views
2

请看看下面的头文件混合型,不支持

#pragma once 
using namespace UsbLibrary; 

ref class MissileLauncher 
{ 
public: 
    MissileLauncher(void); 

private: 
    //Bytes used in command 
    unsigned char UP[10]; 
    unsigned char RIGHT[10]; 
    unsigned char LEFT[10]; 
    unsigned char DOWN[10]; 

    unsigned char FIRE[10]; 
    unsigned char STOP[10]; 
    unsigned char LED_OFF[9]; 
    unsigned char LED_ON[9]; 

    UsbHidPort USB; 
}; 

我使用的是Visual C++项目(C++/CLI?)在Visual Studio专业2010年当我运行这段代码,我得到很多错误

Error 1 error C4368: cannot define 'UP' as a member of managed 'MissileLauncher': mixed types are not supported 
Error 2 error C4368: cannot define 'RIGHT' as a member of managed 'MissileLauncher': mixed types are not supported 
Error 3 error C4368: cannot define 'LEFT' as a member of managed 'MissileLauncher': mixed types are not supported 
Error 4 error C4368: cannot define 'DOWN' as a member of managed 'MissileLauncher': mixed types are not supported 
Error 5 error C4368: cannot define 'FIRE' as a member of managed 'MissileLauncher': mixed types are not supported 
Error 6 error C4368: cannot define 'STOP' as a member of managed 'MissileLauncher': mixed types are not supported 
Error 7 error C4368: cannot define 'LED_OFF' as a member of managed 'MissileLauncher': mixed types are not supported  
Error 8 error C4368: cannot define 'LED_ON' as a member of managed 'MissileLauncher': mixed types are not supported 

在这里,命名空间USBLibrary来自C#的dll文件。该UsbHidPort;是从C#DLL

那么,为什么我收到此错误的对象?有任何想法吗?

+0

我建议阅读[本文档](http://blogs.msdn.com/b/branbray/archive/2005 /07/20/441099.aspx),其中讨论了原生类型,管理类型,以及何时/如何/如果一个可以容纳其他的,在长度这么做。这是一个有点过时,但它的症结会告诉你,你有,为什么你有它的问题,事情可以做了。 – WhozCraig 2013-05-10 20:27:10

回答

6

这实际上不是这种特定情况下的一个问题,至少从什么是可见的,但C++/CLI编译器试图阻止你拍摄你的腿了,导弹的风格。垃圾收集器在压缩堆时移动对象。这使得本地对象非常危险,任何指向它们的指针都将变为无效,并在通过它们写入时破坏GC堆。收集器无法更新这些指针,它无法找到它们。风险太高,所以编译器只是禁止它。

一种替代方法是这些构件作为指针代替声明并分配与在类的构造操作者新的阵列。

private: 
    unsigned char* UP; 
    // etc.. 
public: 
    MissileLauncher() { 
     UP = new unsigned char[10]; 
     // etc.. 
    } 
    ~MissileLauncher() { 
     this->!MissileLauncher(); 
     UP = nullptr; // Destructor may be called more than once 
    } 
    !MissileLauncher() { 
     delete[] UP; 
     // etc... 
    } 

请注意需要析构函数和终结器来释放这些数组的内存。定义析构函数还带来了客户端程序员必须调用它的负担(Dispose()或在C#客户端程序中使用,在C++/CLI程序中删除或堆栈语义),跳过这样一个小的分配不是不合理的。最后但并非最不重要的是,考虑理性解决方案并使用托管阵列:

private: 
    array<Byte>^ UP; 
    // etc.. 
public: 
    MissileLauncher() { 
     UP = gcnew array<Byte>(10); 
     // etc.. 
    } 
+0

太棒了!没有话要谢谢你! – Soldier 2013-05-11 05:11:52

1

的问题是你混合托管和非托管类型是什么编译器警告的手段。该类是一个托管类,但整数数组计为非托管对象。这会导致垃圾收集问题。阅读所有关于它在这里:

http://blogs.msdn.com/b/branbray/archive/2005/07/20/441099.aspx

为什么不使用管理的阵列?

+0

感谢您的回复。我并不喜欢这种被管理的东西。你能不能告诉我如何创建一个托管数组? – Soldier 2013-05-10 20:34:22

+0

没问题。如果你有一个阅读http://www.codeproject.com/Articles/76153/Six-important-NET-concepts-Stack-heap-value-types这基本上解释了所有的价值/参考类型和相应的语法。 int数组是Hans Passant描述的一系列值类型的声明和分配。 – OOhay 2013-05-11 09:11:03