2

我的情况是这样的。

我有 3 个项目。

PrivacyDetectorDLL PDWrapper WindowsFormsApplication1 (C#)

我的目标是在 C# 中使用 Native C++ 类。所以我使用了 C++/Cli 包装类。但我得到保护级别的错误。我不明白。

我得到这个错误!

Error   1   'PDWrapper.PDWrapperClass.m_pCPrivacyDetectEngine' is inaccessible due to its protection level  K:\Visual Studio 2010 Project\PrivacyDetecter\WindowsFormsApplication1\Form1.cs 23

我来自 WindowsFormsApplication1 项目的 c# 代码是这样的。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public PDWrapper.PDWrapperClass m_PDWrapper = null;

        public Form1()
        {
            m_PDWrapper = new PDWrapper.PDWrapperClass();

            unsafe
            {
                m_PDWrapper.m_pCPrivacyDetectEngine->initEngine();
            }

            InitializeComponent();
        }
    }
}

我的 PDWrapper 类看起来像这样。

// PDWrapper.h

#pragma once

using namespace System;

namespace PDWrapper {

    public ref class PDWrapperClass
    {
        // TODO: Add your methods for this class here.
    public :
        PDWrapperClass();
        ~PDWrapperClass();

    public :
        CPrivacyDetectEngine* m_pCPrivacyDetectEngine;
    };
}

这是我的 PrivacyDetectEngine 标头(来自 PDWrapper Project 的标头)

#pragma once
class CPrivacyDetectEngine
{
public: // my func
    CPrivacyDetectEngine(void);
    ~CPrivacyDetectEngine(void);

    void CPrivacyDetectEngine::initEngine();

    void CPrivacyDetectEngine::startEngine(char* currentPath, size_t length);

public: // my util func
    int CPrivacyDetectEngine::bytecmp(unsigned char *a, unsigned char *b, int length);
    void CPrivacyDetectEngine::extToNum(char* fileName, unsigned int* extNum);
    int CPrivacyDetectEngine::checkFileSig(unsigned char* fileSig, int sigLength, char* filePath, char** pFileInternal);
    void CPrivacyDetectEngine::parseMSDocText(char** pFileInternal, unsigned int* compSize, unsigned int* decompSize);
    char* CPrivacyDetectEngine::infData(char* pFileData, int compSize, int decompSize);
    void CPrivacyDetectEngine::privacyDetectXML(char* text, int textLength, int* pItemIndex, char* filePath);
    void CPrivacyDetectEngine::checkSocialNum(char* text);

public: // my var
    int driverCount;            
    char driverName[256];           
    unsigned int parseFileList;     
};

我来自 PrivacyDetectorDLL 的 PrivacyDetectEngine 标头是相同的,但在类 CPrivacyDetectEngine 之间确实有 __declspec(dllexport)

class __declspec(dllexport) CPrivacyDetectEngine

我不知道是什么问题....有人请帮助我。

4

1 回答 1

6

你的“包装”类没有做它的工作。

C# 无法访问本机 C++ 类。这是错误的根源。指针是否存储在托管中ref class并不重要。虽然指针是公共的,但它指向的数据类型对 C# 是隐藏的(因为它不兼容)。

不过,有一个解决方案。C++/CLI 可以很好地访问本机 C++ 类。所以你需要的是:

public ref class PDWrapperClass
{
    // TODO: Add your methods for this class here.
public :
    PDWrapperClass();
    ~PDWrapperClass();

private:
    CPrivacyDetectEngine* m_pCPrivacyDetectEngine;

public:
    void initEngine() { m_pCPrivacyDetectEngine->initEngine(); }
};

您需要为希望 C# 能够调用的每个函数执行此操作。包装器不仅仅是一个指针持有者。在许多情况下,您可以在 C++/CLI 中提供一种方法ref class来调用整个本地函数序列。

不过,请考虑使用智能指针,以确保在所有情况下都释放本机对象。例如,我在 codereview.se 上发布了一个智能指针。如果您使用它,请尊重许可证;这些条款非常慷慨,但确实提出了一些归属要求。

于 2013-05-13T14:44:45.693 回答