libcurl 编译和链接器错误
我尝试在 Visual Studio C++ 中使用 libcurl 和 c++-cli 编写应用程序。它给了我这个错误
error C3867: "fr::Form1::write_data": Dem Funktionsaufruf fehlt die Argumentliste. Verwenden Sie "&fr::Form1::write_data", um einen Zeiger auf den Member zu erstellen. c:\users\ttg\documents\visual studio 2008\projects\fr\fr\Form1.h
,这意味着我应该将一些参数传递给 write_data。我不知道如何传递这些数据,在 libcurl 的文档中它显示了与我完全相同的代码,我只是复制并粘贴了它。我不知道我需要添加什么
此外,当我在表单之外声明此 write_data 函数时,我没有收到此错误,但收到链接器错误,例如:
Fehler 53 error LNK2031: p/invoke konnte nicht für ""extern "C" void __clrcall curl_easy_cleanup(void *)" (?curl_easy_cleanup@@$$J0YMXPAX@Z)" generiert werden. In den Metadaten fehlt die Aufrufkonvention. fr.obj
意思是,元数据中缺少调用约定
这是我的代码:
#pragma once
#include <stdio.h>
#include <stdlib.h>
//#include <unistd.h>
#include <assert.h>
#include <string>
#include <curl/curl.h>
#include <sstream>
#include <curl/easy.h>
#include <iostream>
using namespace std;
namespace fr {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Zusammenfassung für Form1
///
/// Warnung: Wenn Sie den Namen dieser Klasse ändern, müssen Sie auch
/// die Ressourcendateiname-Eigenschaft für das Tool zur Kompilierung verwalteter Ressourcen ändern,
/// das allen RESX-Dateien zugewiesen ist, von denen diese Klasse abhängt.
/// Anderenfalls können die Designer nicht korrekt mit den lokalisierten Ressourcen
/// arbeiten, die diesem Formular zugewiesen sind.
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: Konstruktorcode hier hinzufügen.
//
}
protected:
/// <summary>
/// Verwendete Ressourcen bereinigen.
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
protected:
private:
/// <summary>
/// Erforderliche Designervariable.
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// Erforderliche Methode für die Designerunterstützung.
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
/// </summary>
void InitializeComponent(void)
{
this->SuspendLayout();
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(284, 262);
this->Name = L"Form1";
this->Text = L"Form1";
this->ResumeLayout(false);
}
#pragma endregion
public:
size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
{
// assert(bodyfile == (FILE*) stream); //this assertion fails, but when i comment it, code works. Why?
int written = fwrite(ptr, size, nmemb, (FILE *)stream);
return written;
}
void proc(){
CURL *curl_handle;
const char *headerfilename = "head.out";
FILE *headerfile;
const char *bodyfilename = "body.html";
FILE *bodyfile;
curl_global_init(CURL_GLOBAL_ALL);
curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_URL, "http://url");
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L);
/*this causes error*/curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
headerfile = fopen(headerfilename,"w");
if (headerfile == NULL) {
curl_easy_cleanup(curl_handle);
return;
}
bodyfile = fopen(bodyfilename,"w");
if (bodyfile == NULL) {
curl_easy_cleanup(curl_handle);
return;
}
curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, headerfile);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, bodyfile);
curl_easy_perform(curl_handle);
fclose(headerfile);
fclose(bodyfile);
curl_easy_cleanup(curl_handle);
}//()proc
};
}
I try to code an app with libcurl and c++-cli in visual studio c++. It gives me this error
error C3867: "fr::Form1::write_data": Dem Funktionsaufruf fehlt die Argumentliste. Verwenden Sie "&fr::Form1::write_data", um einen Zeiger auf den Member zu erstellen. c:\users\ttg\documents\visual studio 2008\projects\fr\fr\Form1.h
which means that I should pass some arguments to write_data. I don't know how to pass these data, and in the documentation of libcurl it shows exactly the same code that I have,which I just copy and pasted. I don't know what I need to add
Furthermore when I declare this write_data function outside of the Form I don't get this error but I get linker errors like:
Fehler 53 error LNK2031: p/invoke konnte nicht für ""extern "C" void __clrcall curl_easy_cleanup(void *)" (?curl_easy_cleanup@@$J0YMXPAX@Z)" generiert werden. In den Metadaten fehlt die Aufrufkonvention. fr.obj
meaning, missing call convetion in the metadata
This is my code:
#pragma once
#include <stdio.h>
#include <stdlib.h>
//#include <unistd.h>
#include <assert.h>
#include <string>
#include <curl/curl.h>
#include <sstream>
#include <curl/easy.h>
#include <iostream>
using namespace std;
namespace fr {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Zusammenfassung für Form1
///
/// Warnung: Wenn Sie den Namen dieser Klasse ändern, müssen Sie auch
/// die Ressourcendateiname-Eigenschaft für das Tool zur Kompilierung verwalteter Ressourcen ändern,
/// das allen RESX-Dateien zugewiesen ist, von denen diese Klasse abhängt.
/// Anderenfalls können die Designer nicht korrekt mit den lokalisierten Ressourcen
/// arbeiten, die diesem Formular zugewiesen sind.
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: Konstruktorcode hier hinzufügen.
//
}
protected:
/// <summary>
/// Verwendete Ressourcen bereinigen.
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
protected:
private:
/// <summary>
/// Erforderliche Designervariable.
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// Erforderliche Methode für die Designerunterstützung.
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
/// </summary>
void InitializeComponent(void)
{
this->SuspendLayout();
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(284, 262);
this->Name = L"Form1";
this->Text = L"Form1";
this->ResumeLayout(false);
}
#pragma endregion
public:
size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
{
// assert(bodyfile == (FILE*) stream); //this assertion fails, but when i comment it, code works. Why?
int written = fwrite(ptr, size, nmemb, (FILE *)stream);
return written;
}
void proc(){
CURL *curl_handle;
const char *headerfilename = "head.out";
FILE *headerfile;
const char *bodyfilename = "body.html";
FILE *bodyfile;
curl_global_init(CURL_GLOBAL_ALL);
curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_URL, "http://url");
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L);
/*this causes error*/curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
headerfile = fopen(headerfilename,"w");
if (headerfile == NULL) {
curl_easy_cleanup(curl_handle);
return;
}
bodyfile = fopen(bodyfilename,"w");
if (bodyfile == NULL) {
curl_easy_cleanup(curl_handle);
return;
}
curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, headerfile);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, bodyfile);
curl_easy_perform(curl_handle);
fclose(headerfile);
fclose(bodyfile);
curl_easy_cleanup(curl_handle);
}//()proc
};
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为 write_data 方法应该是静态的...或者像你一样在 Form 类之外...关于链接器错误:摘录自 msdn 文章 尝试将本机函数导入纯映像时,请记住本机编译和纯编译之间的隐式调用约定有所不同。
I think write_data method should be made static... or outside Form class as you did... And about linker error: excerpt from msdn article When attempting to import a native function into a pure image, remember that the implicit calling conventions differ between native and pure compilations.