如何在C语言中调用C++编写的DLL中的函数

 

原文链接: http://www.coopknow.com/papers.asp?paper=2

Many people incorrectly think the C and C++ languages are the same. Although C++ evolved from C and C++ compilers can compile C, the functionality of the two languages is different. C++ is a complete object-oriented language. It supports inheritance, information hiding, polymorphism and operator overloading. C does not have these features.

C++ was originally implemented as a pre-processor to a standard C compiler. The pre-processor parsed the C++ source code and generated C source. A C compiler then compiled the generated source code. There was, however, a problem generating the C source. C++ supports polymorphism (having two or more functions with the same name) but C does not allow two functions to have the same name. They solved this by invoking a pre-processor. It generated a C function name by combining the specified C++ function name and the return and argument types of the function. This solution was called "name mangling." Although modern C++ compilers do not use the pre-processor to generate C source anymore, they still mangle function names. This technique works great so long as all functions involved are C++ functions.

Microsoft Windows DLL external functions do not conform to the C++ naming convention. Their names cannot be mangled by C++ and they do not use the C argument standard. They must be of type PASCAL. In addition, Windows does not support the C++ object/class structure. It just does not know what to do with a pointer to an instantiated object. This does not mean that you cannot use C++ in a DLL, you just need to use a special technique called "wrapping."

C++ Wrappers

This is not a new problem in the C/C++ world. When programmers started using C++ to enhance systems written in C, they needed some way to allow C functions (functions that had no knowledge of C++ calling conventions) to call the methods of C++ objects. They wrote wrapper functions to do this. A wrapper functions is a C function that is compiled as if it were a C++ function. Because the wrapper is compiled as a C++ function, it understands the C++ calling conventions. Since it is a C function, other C functions can call it. Anytime a non-wrapper C function needs to call a C++ class method, it calls the wrapper function and requests the wrapper to make the call for it.

Sample Wrapper Functions

In a Windows DLL, the wrapper functions are the exported functions of the DLL. Let me show a small example of this.
C++ class description in file cls.cpp

class cls
{
public:
cls();
~cls();
int doit(int x);
};
C wrapper functions in file clswrap.cpp:
extern "C"
{
void * PASCAL _extern CLSConstruct();
void PASCAL _extern CLSDestruct(void *Cls);
int PASCAL _extern CLSDoit(void *Cls,int x);
};
void * PASCAL _extern CLSConstruct()
{
cls *obj;

obj = new cls;
return(void *)obj))
}
void PASCAL _extern CLSDestruct(void *Cls)
{
cls *obj;
obj = (cls *)cls;
delete obj;
}
int PASCAL _extern CLSDoit(void *Cls,int x)
{
cls *obj;
obj = (cls *)Cls;
return(obj->doit(x));
}
C function calling the wrapper in file use.C
use()
{
void *cls;
int x;
cls = CLSConstruct();
x = CLSDoit(cls,1);
CLSDestruct(cls);
}

In VB you can use the following:
Declare Function CLSConstruct Lib "cls.dll" As Long
Declare Sub CLSDestruct Lib "cls.lib" (ByVal cls as Long)
Declare Function CLSDoit Lib "cls.lib" (ByVal x as Integer) As Integer

Dim cls as Long
Dim r As Integer
cls = CLSConstruct
r = CLSDoit(cls,2)
CLSDestruct cls

Implementation Notes:

  1. The constructor wrapper function must return a pointer to the object that it instantiated. I use this pointer in all subsequent calls to the wrapper functions. I normally have it as the first argument of all other class method wrapper functions.
  2. I name the wrapper functions with the class name as the first part of the name and the method name as the second part.
  3. If the class method can take different arguments, then I write individual wrapper functions with unique names for each method.

Conclusion

If you want to write Windows DLL's in C++ you certainly can. You just need to write wrapper functions to export the function names to other Windows applications. I recommend that you only use C++ if you plan to use object-oriented programming techniques. If all you need is a simple function that you can easily write in C, why add the complexity of C++ and wrappers?

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值