如何更改我的 C++ 代码以使其在 C 中可用?
Posted
技术标签:
【中文标题】如何更改我的 C++ 代码以使其在 C 中可用?【英文标题】:How can I change my C++ code to make it usable in C? 【发布时间】:2013-04-17 23:34:57 【问题描述】:我似乎遇到了问题。我正在尝试在 c 代码中使用 c++ 函数。
我试过这些方法
http://www.olivierlanglois.net/idioms_for_using_cpp_in_c_programs.html Calling "C++" class member function from "C" code如果我需要完全摆脱课程,那么我会这样做,但我不想丢失控制台的下载提要。
以下是在 c++ 中有效但在 c 中无效的代码。
#include <tchar.h>
#include <urlmon.h>
#pragma comment(lib,"urlmon.lib")
#include <stdio.h>
class MyCallback : public IBindStatusCallback
public:
MyCallback()
~MyCallback()
// This one is called by URLDownloadToFile
STDMETHOD(OnProgress)(/* [in] */ ULONG ulProgress, /* [in] */ ULONG ulProgressMax, /* [in] */ ULONG ulStatusCode, /* [in] */ LPCWSTR wszStatusText)
printf("Downloaded %i of %i byte(s) Status Code = %i\n",ulProgress, ulProgressMax, ulStatusCode);
return S_OK;
// The rest don't do anything...
STDMETHOD(OnStartBinding)(/* [in] */ DWORD dwReserved, /* [in] */ IBinding __RPC_FAR *pib)
return E_NOTIMPL;
STDMETHOD(GetPriority)(/* [out] */ LONG __RPC_FAR *pnPriority)
return E_NOTIMPL;
STDMETHOD(OnLowResource)(/* [in] */ DWORD reserved)
return E_NOTIMPL;
STDMETHOD(OnStopBinding)(/* [in] */ HRESULT hresult, /* [unique][in] */ LPCWSTR szError)
return E_NOTIMPL;
STDMETHOD(GetBindInfo)(/* [out] */ DWORD __RPC_FAR *grfBINDF, /* [unique][out][in] */ BINDINFO __RPC_FAR *pbindinfo)
return E_NOTIMPL;
STDMETHOD(OnDataAvailable)(/* [in] */ DWORD grfBSCF, /* [in] */ DWORD dwSize, /* [in] */ FORMATETC __RPC_FAR *pformatetc, /* [in] */ STGMEDIUM __RPC_FAR *pstgmed)
return E_NOTIMPL;
STDMETHOD(OnObjectAvailable)(/* [in] */ REFIID riid, /* [iid_is][in] */ IUnknown __RPC_FAR *punk)
return E_NOTIMPL;
// IUnknown stuff
STDMETHOD_(ULONG,AddRef)()
return 0;
STDMETHOD_(ULONG,Release)()
return 0;
STDMETHOD(QueryInterface)(/* [in] */ REFIID riid, /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
return E_NOTIMPL;
;
int main()
MyCallback pCallback;
HRESULT url = URLDownloadToFile(NULL,_T("https://dl.dropboxusercontent.com/u/102222417/jediAcademy.zip"),_T("C:\\JKA\\file.zip"),0,&pCallback);
if(url == S_OK)
printf("Successful!");
getchar();
else if(url == E_OUTOFMEMORY)
printf("Not enough memory!");
else if (url == INET_E_DOWNLOAD_FAILURE)
printf("ERROR: INET invalid resource");
return 0;
在 C 代码中运行时出现此错误
1>------ Build started: Project: Downloader++, Configuration: Debug
Win32 ------ 2012\projects\downloader++\downloader++\main.c(101):
error C2061: syntax error : identifier 'MyCallback'
2012\projects\downloader++\downloader++\main.c(101): error C2059:
syntax error : ';'
2012\projects\downloader++\downloader++\main.c(101): error C2059:
syntax error : ':'
2012\projects\downloader++\downloader++\main.c(150): error C2065:
'MyCallback' : undeclared identifier
2012\projects\downloader++\downloader++\main.c(150): error C2146:
syntax error : missing ';' before identifier 'pCallback'
2012\projects\downloader++\downloader++\main.c(150): error C2065:
'pCallback' : undeclared identifier 1>
studio 2012\projects\downloader++\downloader++\main.c(151): error
C2275: 'HRESULT' : illegal use of this type as an expression 1>
c:\program files (x86)\windows kits\8.0\include\um\winnt.h(556) : see
declaration of 'HRESULT'
2012\projects\downloader++\downloader++\main.c(151): error C2146:
syntax error : missing ';' before identifier 'url'
1>c:\users\gamer\documents\visual studio
2012\projects\downloader++\downloader++\main.c(151): error C2065:
'url' : undeclared identifier 1>c:\users\gamer\documents\visual studio
2012\projects\downloader++\downloader++\main.c(151): error C2065:
'pCallback' : undeclared identifier
2012\projects\downloader++\downloader++\main.c(151): warning C4133:
'function' : incompatible types - from 'int *' to
'LPBINDSTATUSCALLBACK'
2012\projects\downloader++\downloader++\main.c(153): error C2065:
'url' : undeclared identifier
2012\projects\downloader++\downloader++\main.c(159): error C2065:
'url' : undeclared identifier
2012\projects\downloader++\downloader++\main.c(164): error C2065:
'url' : undeclared identifier 1> Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
谢谢你:)
【问题讨论】:
"class" 不是 C 代码中的有效关键字。 有没有办法转换代码以便在 c 中工作? 不是这个代码。您必须实现类之外的所有方法(这将是 C 中的struct
)。用 C 语言编写 COM coclass 对象并非不可能;太乏味了,网上应该有很多这样的例子。基本的症结是你提供一个函数指针的结构,然后在结构定义之外实现它们。不是为了非 C 函数指针的狡猾虚伪,而是可行的。
你能举个例子吗?
通常您会使用 C++ 编译器编译 C++ 代码,并制作一些您的 C 代码将调用的外部“C”函数来处理 C++ 代码。
【参考方案1】:
一种常见的技术是编写包装函数,其中指向类实例的指针在传递给 C 时被视为 void*
。然后,您公开一个函数,例如:
extern "C" MyClass_OnProgress(/* [in] */ void* instance, /* [in] */ ULONG ulProgress, /* [in] */ ULONG ulProgressMax, /* [in] */ ULONG ulStatusCode, /* [in] */ LPCWSTR wszStatusText)
MyClass* _this = static_cast<MyClass*>(instance);
_this->OnProgress(ulProgess, ulProgressMax, ulStatusCode, wszStatusText);
注意:上面缺少返回类型,因为我不知道 STDMETHOD 宏声明的返回值是什么。
另外,放弃匈牙利符号。这很烦人,已经失宠了。甚至微软也不建议在新代码中使用它。
【讨论】:
我尝试了你的建议,但是在编译时编译器在类上给出了一个错误(我将你的 MyClass MyCallback 重命名为我的代码)也尝试了这个 extern "C"ULONG MyClass_OnProgress(/* [in] /void instance, /* [in] / ULONG ulProgress, / [in] / ULONG ulProgressMax, / [in] / ULONG ulStatusCode, / [in] / LPCWSTR wszStatusText) MyCallback _this = static_cast以上是关于如何更改我的 C++ 代码以使其在 C 中可用?的主要内容,如果未能解决你的问题,请参考以下文章
如何隐藏 DefaultTableModel 中的特定列以使其在表中显示?
如何在 4.5 之后附加零以使其在 PHP 中成为 4.50? [复制]