在 C++ 本机代码中使用 C++/CLI 库以及如何 link
Use C++/CLI Library in C++ native code and how to link
我想使用一些执行 http-post 的代码,因为我不太熟悉 c++ 和你可以使用的库,而且我可能太笨了,无法获得 libcurl 和 curlpp为了工作,我找到了 link 解释如何使用 .net 版本。
好的,所以我创建了一个 class。头文件:
public ref class Element
{
public:
Element();
virtual ~Element();
void ExecuteCommand();
};
Class 文件:
#include "Element.h"
Element::Element()
{
}
Element::~Element()
{
Console::WriteLine("deletion");
}
void Element::ExecuteCommand(){
HttpWebRequest^ request = dynamic_cast<HttpWebRequest^>(WebRequest::Create("http://www.google.com"));
request->MaximumAutomaticRedirections = 4;
request->MaximumResponseHeadersLength = 4;
request->Credentials = gcnew NetworkCredential("username", "password", "domain");
HttpWebResponse^ response = dynamic_cast<HttpWebResponse^>(request->GetResponse());
Console::WriteLine("Content length is {0}", response->ContentLength);
Console::WriteLine("Content type is {0}", response->ContentType);
// Get the stream associated with the response.
Stream^ receiveStream = response->GetResponseStream();
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader^ readStream = gcnew StreamReader(receiveStream, Encoding::UTF8);
Console::WriteLine("Response stream received.");
Console::WriteLine(readStream->ReadToEnd());
response->Close();
readStream->Close();
}
如果我将此项目的配置类型设置为应用程序 (exe),并创建一个新的 .cpp 文件,我在其中创建此元素的实例,它就可以正常工作。
但我的问题是:是否可以从此项目创建一个 .dll/.lib 库并在没有 CLI 的情况下在 C++ 项目中使用它? (我不想使用 ^ 作为指针 :( )
即使不可能,我还有一个问题。
当我 link C++/CLI 项目中的库时。我得到
unresolved token (06000001) Element::.ctor
unresolved token (06000002) Element::~Element
unresolved token (06000003) Element::ExecuteCommand
3 unresolved externals
第二个项目中main.cpp的代码如下:
#include <Element.h>
int main(){
return 0;
}
谢谢
正如 Hans Passant 所说:您必须 将您的 C++/CLI 代码编译为动态库,以便能够从非托管应用程序中使用它。 CLI/Managed 代码不能 运行 from/cannot 驻留在静态库中。
如果您将 C++/CLI 库目标从静态库更改为动态库,您将能够成功编译您的非托管 C++ 应用程序。
我的一个想法:
我认为如果您使用混合模式 C++/CLI DLL 来使用托管功能会更好 - 您将能够使您的消费者应用程序完全摆脱引用 CLR 的束缚。
您的元素 class 的此类混合模式包装器的 Header 将如下所示:
#pragma once
#pragma unmanaged
#if defined(LIB_EXPORT)
#define DECLSPEC_CLASS __declspec(dllexport)
#else
#define DECLSPEC_CLASS __declspec(dllimport)
#endif
class ElementWrapperPrivate;
class __declspec(dllexport) ElementWrapper
{
private:
ElementWrapperPrivate* helper;
public:
ElementWrapper();
~ElementWrapper();
public:
void ExecuteCommand();
};
实现如下所示:
#include "ElementWrapper.h"
#pragma managed
#include "Element.h"
#include <msclr\auto_gcroot.h>
using namespace System::Runtime::InteropServices;
class ElementWrapperPrivate
{
public:
msclr::auto_gcroot<Element^> elementInst; // For Managed-to-Unmanaged marshalling
};
ElementWrapper::ElementWrapper()
{
helper = new ElementWrapperPrivate();
helper->elementInst = gcnew Element();
}
ElementWrapper::~ElementWrapper()
{
delete helper;
}
void ElementWrapper::ExecuteCommand()
{
helper->elementInst->ExecuteCommand();
}
然后只需将 Element.cpp + ElementWrapper.cpp 编译为 DLL 并在非托管应用程序中使用 ElementWrapper.h。
我想使用一些执行 http-post 的代码,因为我不太熟悉 c++ 和你可以使用的库,而且我可能太笨了,无法获得 libcurl 和 curlpp为了工作,我找到了 link 解释如何使用 .net 版本。
好的,所以我创建了一个 class。头文件:
public ref class Element
{
public:
Element();
virtual ~Element();
void ExecuteCommand();
};
Class 文件:
#include "Element.h"
Element::Element()
{
}
Element::~Element()
{
Console::WriteLine("deletion");
}
void Element::ExecuteCommand(){
HttpWebRequest^ request = dynamic_cast<HttpWebRequest^>(WebRequest::Create("http://www.google.com"));
request->MaximumAutomaticRedirections = 4;
request->MaximumResponseHeadersLength = 4;
request->Credentials = gcnew NetworkCredential("username", "password", "domain");
HttpWebResponse^ response = dynamic_cast<HttpWebResponse^>(request->GetResponse());
Console::WriteLine("Content length is {0}", response->ContentLength);
Console::WriteLine("Content type is {0}", response->ContentType);
// Get the stream associated with the response.
Stream^ receiveStream = response->GetResponseStream();
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader^ readStream = gcnew StreamReader(receiveStream, Encoding::UTF8);
Console::WriteLine("Response stream received.");
Console::WriteLine(readStream->ReadToEnd());
response->Close();
readStream->Close();
}
如果我将此项目的配置类型设置为应用程序 (exe),并创建一个新的 .cpp 文件,我在其中创建此元素的实例,它就可以正常工作。
但我的问题是:是否可以从此项目创建一个 .dll/.lib 库并在没有 CLI 的情况下在 C++ 项目中使用它? (我不想使用 ^ 作为指针 :( )
即使不可能,我还有一个问题。 当我 link C++/CLI 项目中的库时。我得到
unresolved token (06000001) Element::.ctor
unresolved token (06000002) Element::~Element
unresolved token (06000003) Element::ExecuteCommand
3 unresolved externals
第二个项目中main.cpp的代码如下:
#include <Element.h>
int main(){
return 0;
}
谢谢
正如 Hans Passant 所说:您必须 将您的 C++/CLI 代码编译为动态库,以便能够从非托管应用程序中使用它。 CLI/Managed 代码不能 运行 from/cannot 驻留在静态库中。 如果您将 C++/CLI 库目标从静态库更改为动态库,您将能够成功编译您的非托管 C++ 应用程序。
我的一个想法: 我认为如果您使用混合模式 C++/CLI DLL 来使用托管功能会更好 - 您将能够使您的消费者应用程序完全摆脱引用 CLR 的束缚。
您的元素 class 的此类混合模式包装器的 Header 将如下所示:
#pragma once
#pragma unmanaged
#if defined(LIB_EXPORT)
#define DECLSPEC_CLASS __declspec(dllexport)
#else
#define DECLSPEC_CLASS __declspec(dllimport)
#endif
class ElementWrapperPrivate;
class __declspec(dllexport) ElementWrapper
{
private:
ElementWrapperPrivate* helper;
public:
ElementWrapper();
~ElementWrapper();
public:
void ExecuteCommand();
};
实现如下所示:
#include "ElementWrapper.h"
#pragma managed
#include "Element.h"
#include <msclr\auto_gcroot.h>
using namespace System::Runtime::InteropServices;
class ElementWrapperPrivate
{
public:
msclr::auto_gcroot<Element^> elementInst; // For Managed-to-Unmanaged marshalling
};
ElementWrapper::ElementWrapper()
{
helper = new ElementWrapperPrivate();
helper->elementInst = gcnew Element();
}
ElementWrapper::~ElementWrapper()
{
delete helper;
}
void ElementWrapper::ExecuteCommand()
{
helper->elementInst->ExecuteCommand();
}
然后只需将 Element.cpp + ElementWrapper.cpp 编译为 DLL 并在非托管应用程序中使用 ElementWrapper.h。