【问题标题】:__stdcall typedef struct__stdcall typedef 结构
【发布时间】:2018-02-26 10:02:10
【问题描述】:

我正在用 C++ 编写我的第一个 DLL。使用__declspec(dll_export),我可以使用 C 包装器在 Python 和 C++ 上阅读它。但是我现在也想在 C 上阅读它,所以我现在必须添加 __stdcall 约定。但我不知道如何将其应用于typedef struct。例如:

Projet.h

#pragma once
#include "Projet_inc.h"

class Projet // before, class _declspec(dll_export) Projet
{
public:
    Projet();
    ~Projet();

    int multiply(int arg1, int arg2);
    int result;
};

Projet_inc.h

#ifdef PROJET_EXPORTS
#  define EXPORT __declspec(dllexport)
#else
#  define EXPORT __declspec(dllimport)
#endif

#define CALLCONV_API __stdcall // before, this line didn't exist

extern "C" // C wrapper
{
    typedef struct Projet Projet; // make the class opaque to the wrapper

    Projet* EXPORT CALLCONV_API cCreateObject(void);
    int EXPORT CALLCONV_API cMultiply(Projet* pDLLobject, int arg1, int arg2);
}

Projet.cpp

#include "stdafx.h"
#include "Projet.h"

Projet::Projet() {}
Projet::~Projet() {}

int Projet::multiply(int arg1, int arg2) {
    result = arg1 * arg2;
    return result;
}

Projet* EXPORT CALLCONV_API  cCreateObject(void)
{
    return new Projet();
}

int EXPORT CALLCONV_API  cMultiply(Projet* pDLLtest, int arg1, int arg2)
{
    if (!pDLLtest)
        return 0;
    return pDLLtest->multiply(arg1, arg2);
}

在 Visual Studio 2017 上,编译返回(第一行):

dir\projet_inc.h(11) : warning C4229: anachronisme utilisé : modificateurs de données ignorés
dir\projet_inc.h(13) :error C2059: erreur de syntaxe : '__declspec(dllimport)'

而且 MSDN 告诉我,对于 C2059 错误,我必须先检查 typedef 结构。

【问题讨论】:

  • 调用约定适用于可调用函数,而不是结构。
  • stdcall 与 C 和 C++ 之间的互操作性无关。
  • 我同意这个,但是因为没有这个它不会工作,我试过这个并忘记在发布之前删除它:(

标签: c++ struct typedef stdcall


【解决方案1】:

导出说明符仅适用于函数和变量。调用约定说明符仅适用于函数。所以类型别名(C 风格)应该是这样的:

typedef struct Projet_I2M Projet_I2M;

出口规范应在声明前:

EXPORT Projet * CALLCONV_API cCreateObject(void);

您似乎有意导出 C 接口,因此您应该防止 C++ 异常跨越语言边界。

extern "C" 应有条件地包含:

#ifdef __cplusplus
extern "C"
{
#endif

#ifdef __cplusplus
}
#endif

【讨论】:

  • 我同意这一点,因为这是我所理解的,但我仍然有同样的错误信息。
  • @MathieuGauquelin 我已经更新了我的答案。 EXPORT 应该在返回类型之前。
  • 我没有考虑将 EXPORT 和 CALLCONV_API 分开放置。谢谢。你知道为什么 Visual 警告我现在 C 包装器的所有功能都存在不一致的 Dll 链接吗?
  • @MathieuGauquelin 我不知道,但这个问题很可能已经被问过了。
猜你喜欢
  • 2011-05-30
  • 1970-01-01
  • 2010-11-20
  • 2015-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多