C++控制台应用程序调用C++/CLI静态库
C++ console app call C++/CLI static library
我正在考虑创建一个C++/CLI静态库的想法,该库为托管EventLogger功能公开了许多静态函数。我当前的解决方案存在于/clr
编译的C++项目和C++控制台应用程序之外。
Visual Studio告诉我ConsoleApp需要使用/clr
参数进行编译,但这是我不想做的事情。有什么方法可以实现我在这里要做的吗?
#### ConsoleApp.cpp
#include <iostream>
#include "../ClrEtwLogger/ClrEtwLogger.h"
int main()
{
clr_etw_logger::etw_logger::etw_log();
}
#### ClrEtwLogger.h (/clr), static library
#pragma once
#using <system.dll>
using namespace System;
using namespace Diagnostics;
namespace clr_etw_logger
{
public ref class etw_logger
{
public:
static void etw_log()
{
const auto source = gcnew String("dotNet ClrEtwLogger");
const auto log = gcnew String("EtwLogger");
const auto event = gcnew String("Sample Event 1");
if (!EventLog::SourceExists(source))
{
EventLog::CreateEventSource(source, log);
}
EventLog::WriteEntry(source, event);
EventLog::WriteEntry(source, event, EventLogEntryType::Warning, 234);
}
};
}
是的,您可以将托管代码封装在非托管函数中,并按照以下步骤从托管项目中调用它,
1>创建一个空项目c++项目
2>在配置->中将公共语言运行时支持设置为公共语言运行时间支持(/clr(高级页面
3>配置中>C++>命令行,添加此文本以清除链接器错误->/Zc:to-
4>将.NET版本设置为您在配置->中安装的版本.NET Framework版本字段中的高级页面,例如4.8
5>添加对必要的Dlls 的引用
在我的例子中,我引用了以下程序集
System
System.Data
System.Windows.Forms
System.Drawing
6>在配置->常规页面,将配置类型更改为静态库,
7>在配置->高级页面,将目标文件扩展名更改为.lib在本例中,代码在main.cpp中编译,没有头文件
using namespace System;
using namespace System::Threading;
using namespace System::Windows::Forms;
using namespace System::Windows;
namespace MyApp
{
public ref class MyForm : public Form
{
public:
MyForm() {
InitializeComponent();
}
ProgressBar^ GetProgressBar() {
return pgb;
}
protected:
~MyForm() {
}
private:
ProgressBar^ pgb;
void InitializeComponent() {
pgb = gcnew ProgressBar();
SuspendLayout();
//
// progressBar
//
pgb->Dock = DockStyle::Fill;
pgb->Location = Drawing::Point(0, 0);
pgb->Name = "pgb";
pgb->Size = Drawing::Size(200, 20);
pgb->TabIndex = 0;
//
// MyForm
//
ClientSize = Drawing::Size(200, 20);
Controls->Add(pgb);
auto fs = Forms::FormBorderStyle::FixedSingle;
this->FormBorderStyle = fs;
MaximizeBox = false;
MinimizeBox = false;
Name = "MyForm";
auto sp = FormStartPosition::CenterScreen;
StartPosition = sp;
Text = "My Form";
ResumeLayout(false);
}
};
}
void ShowProgress() {
auto f = gcnew MyApp::MyForm();
f->TopMost = true;
f->Show();
f->GetProgressBar()->Visible = true;
f->GetProgressBar()->Minimum = 1;
f->GetProgressBar()->Maximum = 100;
f->GetProgressBar()->Value = 90;
f->GetProgressBar()->Step = 1;
auto fv = f->GetProgressBar()->Value;
while (fv < 10)
{
f->GetProgressBar()->Value += 1;
Thread::Sleep(1);
f->Update();
}
f->Close();
}
void RunProgress() {
try {
auto ts = gcnew ThreadStart(ShowProgress);
auto t = gcnew Thread(ts);
t->SetApartmentState(ApartmentState::STA);
t->Start();
t->Join();
}
catch (Exception^ e) {
// TODO: Handle any exceptions
}
}
void ShowProgressBar()
{
MyApp::MyForm^ form = nullptr;
form = gcnew MyApp::MyForm();
form->TopMost = true;
form->Show();
form->GetProgressBar()->Visible = true;
form->GetProgressBar()->Minimum = 1;
form->GetProgressBar()->Maximum = 100;
form->GetProgressBar()->Value = 1;
form->GetProgressBar()->Step = 1;
auto i = 0;
if (form)
{
while (form->GetProgressBar()->Value < 100)
{
form->GetProgressBar()->Value += 1;
form->Update();
Thread::Sleep(1);
}
form->Close();
}
}
//this is the function to be exported
extern "C" void RunProgressBar()
{
try
{
Thread^ progressBarThread = gcnew Thread(gcnew ThreadStart(ShowProgressBar));
progressBarThread->SetApartmentState(ApartmentState::STA);
progressBarThread->Start();
progressBarThread->Join();
}
catch (System::Exception^ e)
{
// Your main application code here
}
}
然后您可以从非托管项目中调用代码通过引用库并定义导入的函数,如
#pragma comment(lib, "RunProgressBarLib.lib")
// Creates a progress bar for
//a short amount of time
extern "C" void RunProgressBar();
您可以使用的c++版本有一些限制,c++17可能与clr、不兼容
在.NET级别处理异常也很重要,以免它们导致非托管代码崩溃。
相关文章:
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- #为""定义宏;静态";针对不同的上下文
- cmake如何在fedora工作站中找到boost静态库包
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 将公共但非静态的成员函数与ALGLIB集成
- cmake在我的项目中所需的所有静态库都不成功
- C++从另一个类访问公共静态向量的正确方法是什么
- 基于boost的程序的静态链接——zlib问题
- 在静态库中嵌入类方法
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 如何在C++中获得"静态纯虚拟"功能?
- 私有类型的静态常量成员
- 使用gcc从静态链接的文件中查找可选符号
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 如何在C++中使用非静态成员函数作为回调函数
- 将静态库链接到不带-fPIC的共享库中
- 静态结构和一个定义规则
- 为什么虚函数不能是静态的和全局的?
- C++17中函数模板中的静态数组初始化(MSVC 2019)
- 停止cmake target_link_libraries将插件中静态库的两个对象文件链接到静态库本身