Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何导出C++;类作为dll? 我来自C/java背景,所以我想知道如何创建C++类似于C语言的DLL。_C++_Visual Studio_Class_Dllexport - Fatal编程技术网

如何导出C++;类作为dll? 我来自C/java背景,所以我想知道如何创建C++类似于C语言的DLL。

如何导出C++;类作为dll? 我来自C/java背景,所以我想知道如何创建C++类似于C语言的DLL。,c++,visual-studio,class,dllexport,C++,Visual Studio,Class,Dllexport,我已经尝试了\uuudeclspec(dllexport)和\uudeclspec(dllimport),但我只设法让它在静态方法上工作。我相信这是由于我的理解有限 我如何导出C++中的类(包括私有成员),并能够在引用端实例化它们,就像我将用C?一些指向在线资源/教程的指针也可以做到这一点 我开始使用MFCDLL模板,老实说,我不知道90%的模板是用来做什么的,也不知道为什么我要继承CWinApp。我试图用ccppracielibraryapp标记该类,但它不再编译 // CppPractice

我已经尝试了
\uuudeclspec(dllexport)
\uudeclspec(dllimport)
,但我只设法让它在静态方法上工作。我相信这是由于我的理解有限

我如何导出C++中的类(包括私有成员),并能够在引用端实例化它们,就像我将用C?一些指向在线资源/教程的指针也可以做到这一点

我开始使用MFCDLL模板,老实说,我不知道90%的模板是用来做什么的,也不知道为什么我要继承CWinApp。我试图用
ccppracielibraryapp
标记该类,但它不再编译

// CppPracticeLibrary.h : main header file for the CppPracticeLibrary DLL
//


#pragma once

#ifndef __AFXWIN_H__
    #error "include 'stdafx.h' before including this file for PCH"
#endif

#include "resource.h"       // main symbols

#ifdef CCppPracticeLibraryApp_EXPORTS
#define CCppPracticeLibraryApp_API __declspec(dllexport) 
#else
#define CCppPracticeLibraryApp_API __declspec(dllimport) 
#endif

// CCppPracticeLibraryApp
// See CppPracticeLibrary.cpp for the implementation of this class
//

class CCppPracticeLibraryApp : public CWinApp
{
public:
    CCppPracticeLibraryApp();
    static CCppPracticeLibraryApp_API void SayHelloWorld();
// Overrides
public:
    virtual BOOL InitInstance();

    DECLARE_MESSAGE_MAP()
};
定义文件:

//cppracticelibrary.cpp:定义DLL的初始化例程

#include "stdafx.h"
#include "CppPracticeLibrary.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#define CCppPracticeLibraryApp_EXPORTS



BEGIN_MESSAGE_MAP(CCppPracticeLibraryApp, CWinApp)
END_MESSAGE_MAP()


// CCppPracticeLibraryApp construction

CCppPracticeLibraryApp::CCppPracticeLibraryApp()
{
    // TODO: add construction code here,
    // Place all significant initialization in InitInstance
}

void CCppPracticeLibraryApp::SayHelloWorld()
{
    printf( "Hello world");
}


// The one and only CCppPracticeLibraryApp object

CCppPracticeLibraryApp theApp;


// CCppPracticeLibraryApp initialization

BOOL CCppPracticeLibraryApp::InitInstance()
{
    CWinApp::InitInstance();

    return TRUE;
}
客户端/引用方法

// TestConsoleApplication.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "TestConsoleApplication.h"
#include "CppPracticeLibrary.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// The one and only application object

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;

    HMODULE hModule = ::GetModuleHandle(NULL);

    if (hModule != NULL)
    {
        // initialize MFC and print and error on failure
        if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
        {
            // TODO: change error code to suit your needs
            _tprintf(_T("Fatal Error: MFC initialization failed\n"));
            nRetCode = 1;
        }
        else
        {
            // TODO: code your application's behavior here.
            /*CCppPracticeLibraryApp* testCallingLibrary =  new CCppPracticeLibraryApp();
            testCallingLibrary->SayHelloWorld();*/
            CCppPracticeLibraryApp::SayHelloWorld();
        }
    }
    else
    {
        // TODO: change error code to suit your needs
        _tprintf(_T("Fatal Error: GetModuleHandle failed\n"));
        nRetCode = 1;
    }

    return nRetCode;
}
我希望能够在上述代码中取消注释以下行:

        /*CCppPracticeLibraryApp* testCallingLibrary =  new CCppPracticeLibraryApp();
        testCallingLibrary->SayHelloWorld();*/

为了导出类的所有成员,您可以在类的声明中包含
declspec
,如下所示

class __declspec(dllexport) ExportedClass
{
    //....
};

要导出类中的所有公共数据成员和成员函数,关键字必须出现在类名的左侧,如下所示:

class __declspec(dllexport) CExampleExport : public CObject
{ ... class definition ... };

也可以考虑,有更多的方法可以做到这一点,比如<代码> .DEF文件。 花点时间阅读MSDN站点上的解释。

使用u declspec(dllexport)和u declspec(dllimport),您只需创建一种api,可用于从dll导出方法或成员。通过导出此方法,您可以从另一个dlll访问它。您可以做的是创建一个头文件,在其中定义导出宏

    ifdef MYPROJECT_EXPORTS
      define MYPROJECT_EXPORTS__declspec( dllexport )
   else 
       define MYPROJECT_EXPORTS__declspec( dllimport )
   endif 
在声明方法时,如果要导出方法,只需将宏放在方法声明之前,如下所示:

MYPROJECT_EXPORTS void myMethod();
您还必须将符号添加到预处理器定义中(在MS Visual Studio-->项目属性-->C/C++-->预处理器-->预处理器定义中)。

您必须阅读此主题

请注意,如果在边界处使用C++类(包括MFC类或STL类)构建DLL,则DLL客户端必须使用相同的VC++编译器版本和相同的CRT风格(例如,多线程DLL调试CRT、多线程DLL发布CRT和其他“更微妙”的CRT)设置,例如,相同的
\u具有\u迭代器\u调试
设置),以构建将使用DLL的EXE

相反,如果您从DLL导出“强”>纯C接口< /强>(但是您可以在DLL内部使用C++,就像Win32 API),或者如果构建了CistDLL,DLL客户端可以使用不同版本的VC++编译器(甚至不同的CRT)使用DLL。


此外,还要注意上述文章定义的内容(即使用抽象接口).

请显示您的代码…@bash.d已用代码更新。然后,我可以
新建
引用代码上的类
CExampleExport
吗?因为通读该文章时,它说它将只导出
public
成员。这是否意味着实例化的类仍然可以访问私有成员,只是它们不会被访问ible或它们将不会被导入,period?@Alwyn它导出一个类的所有成员,包括内部编译器生成的代码和数据,如vtable、隐式生成的成员函数、RTTI等。这是关于可见性范围的。您正在创建DLL的入口点,可以使用它。这只是意味着您不能将这也是正确的答案:(如果我能给你们两个打上正确的标记,我会的。但是我给+1。