Mar*_*ork 31
Foreach公共方法你需要一个C函数.
您还需要一个不透明的指针来表示C代码中的类.
虽然你可以构建一个包含void*和其他信息的结构(例如,如果你想支持数组?),那么使用void*就更简单了.
Fred.h
--------------------------------
#ifdef  __cplusplus
class Fred
{
    public:
    Fred(int x,int y);
    int doStuff(int p);
};
#endif
//
// C Interface.
typedef void*   CFred;
//
// Need an explicit constructor and destructor.
extern "C" CFred  newCFred(int x,int y);
extern "C" void   delCFred(CFred);
//
// Each public method. Takes an opaque reference to the object
// that was returned from the above constructor plus the methods parameters.
extern "C" int    doStuffCFred(CFred,int p);
实施是微不足道的.
将不透明指针转换为Fred,然后调用该方法.
CFred.cpp
--------------------------------
// Functions implemented in a cpp file.
// But note that they were declared above as extern "C" this gives them
// C linkage and thus are available from a C lib.
CFred newCFred(int x,int y)
{
    return reinterpret_cast<void*>(new Fred(x,y));
}
void delCFred(CFred fred)
{
    delete reinterpret_cast<Fred*>(fred);
}
int doStuffCFred(CFred fred,int p)
{
    return reinterpret_cast<Fred*>(fred)->doStuff(p);
}
cod*_*nd1 18
虽然Loki Astari的答案非常好,但他的示例代码将包装代码放在C++类中.我更喜欢将包装代码放在一个单独的文件中.另外我认为使用类名称为包装C函数添加前缀是更好的样式.
以下博客文章介绍了如何执行此操作:http: //blog.eikke.com/index.php/ikke/2005/11/03/using_c_classes_in_c.html
我复制了必不可少的部分,因为博客被遗弃并可能最终消失(归功于Ikke的博客):
首先我们需要一个C++类,使用一个头文件(Test.hh)
class Test {
    public:
        void testfunc();
        Test(int i);
    private:
        int testint;
};
和一个实现文件(Test.cc)
#include <iostream>
#include "Test.hh"
using namespace std;
Test::Test(int i) {
    this->testint = i;
}
void Test::testfunc() {
    cout << "test " << this->testint << endl;
}
这只是基本的C++代码.
然后我们需要一些胶水代码.这段代码介于C和C++之间.同样,我们有一个头文件(TestWrapper.h,只是.h,因为它不包含任何C++代码)
typedef void CTest;
#ifdef __cplusplus
extern "C" {
#endif
CTest * test_new(int i);
void test_testfunc(const CTest *t);
void test_delete(CTest *t);
#ifdef __cplusplus
}
#endif
和函数实现(TestWrapper.cc,.cc,因为它包含C++代码):
#include "TestWrapper.h"
#include "Test.hh"
extern "C" {
    CTest * test_new(int i) {
        Test *t = new Test(i);
        return (CTest *)t;
    }
    void test_testfunc(const CTest *test) {
        Test *t = (Test *)test;
        t->testfunc();
    }
    void test_delete(CTest *test) {
        Test *t = (Test *)test;
        delete t;
    }
}
根据我的经验的一些意见:
例如:
C_ERROR BuildWidget(HUI ui, HWIDGET* pWidget);
例如你的函数应该是这样的:
C_ERROR BuildWidget(HUI ui, HWIDGET* pWidget){
    Ui* ui = (Ui*)ui;
    if(ui.Signature != 1234)
    return BAD_HUI;
}
例如:
C_ERROR CreateUi(HUI* ui);
C_ERROR CloseUi(HUI hui); // usually error codes don't matter here, so may use void
例如:
C_ERROR CreateBitmap(HUI* ui, SIZE size, char** pBmpBuffer, int* pSize);
Image并通过句柄提供对其的访问HIMG,请提供将其与 Windows HBITMAP 之间进行转换的函数)。这将简化与现有 API 的集成。例如
C_ERROR BitmapToHBITMAP(HUI* ui, char* bmpBuffer, int size, HBITMAP* phBmp);
首先,您可能不需要将所有方法都转换为 C 函数。如果您可以简化 API 并隐藏一些 C++ 接口,那就更好了,因为在更改 C++ 逻辑时,您可以最大限度地减少更改 C API 的机会。
因此,请考虑通过该 API 提供更高级别的抽象。使用您描述的 void* 解决方案。它在我看来是最合适的(或 typedef void* 作为 HANDLE :))。