我似乎有问题。我正在尝试获取要在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> ------开始构建:项目:Downloader ++,配置:调试
Win32 ------ 2012 \ projects \ downloader ++ \ downloader ++ \ main.c(101):
错误C2061:语法错误:标识符'MyCallback'
2012 \ projects \ downloader ++ \ downloader ++ \ main.c(101):错误C2059:
语法错误:“;”
2012 \ projects \ downloader ++ \ downloader ++ \ main.c(101):错误C2059:
语法错误:“:”
2012 \ projects \ downloader ++ \ downloader ++ \ main.c(150):错误C2065:
'MyCallback':未声明的标识符
2012 \ projects \ downloader ++ \ downloader ++ \ main.c(150):错误C2146:
语法错误:缺少';'在标识符“ pCallback”之前
2012 \ projects \ downloader ++ \ downloader ++ \ main.c(150):错误C2065:
'pCallback':未声明的标识符1>
studio 2012 \ projects \ downloader ++ \ downloader ++ \ main.c(151):错误
C2275:“ HRESULT”:非法使用此类型作为表达式1>
c:\ program files(x86)\ windows kits \ 8.0 \ include \ um \ winnt.h(556):请参阅
声明“ HRESULT”
2012 \ projects \ downloader ++ \ downloader ++ \ main.c(151):错误C2146:
语法错误:缺少';'在标识符“ url”之前
1> c:\ users \ gamer \ documents \ visual studio
2012 \ projects \ downloader ++ \ downloader ++ \ main.c(151):错误C2065:
'url':未声明的标识符1> c:\ users \ gamer \ documents \ visual studio
2012 \ projects \ downloader ++ \ downloader ++ \ main.c(151):错误C2065:
'pCallback':未声明的标识符
2012 \ projects \ downloader ++ \ downloader ++ \ main.c(151):警告C4133:
'function':不兼容的类型-从'int *'到
'LPBINDSTATUSCALLBACK'
2012 \ projects \ downloader ++ \ downloader ++ \ main.c(153):错误C2065:
'url':未声明的标识符
2012 \ projects \ downloader ++ \ downloader ++ \ main.c(159):错误C2065:
'url':未声明的标识符
2012 \ projects \ downloader ++ \ downloader ++ \ main.c(164):错误C2065:
'url':未声明的标识符1>正在生成代码...
==========构建:0成功,1失败,0最新,跳过0 ==========
谢谢 :)
最佳答案
一种常见的技术是编写包装函数,其中将指向您的类实例的指针传递给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宏将其声明为返回值。
另外,删除匈牙利表示法。这很烦人,已经失宠了。甚至Microsoft也建议不要在新代码中使用它。