环境
- VS2019
- 安装CLR项目
使用CLR
创建被调用的C++空项目
- 设置vs2019宏定义
- 创建空项目Caculate2
- 修改为生成动态库
- 设置生成64为平台(这个前后统一即可)
- 添加类CaculateData
头文件CaculateData.h
#ifdef CaculateDLL_EXPORTS
#define Calculate_EXPORTS __declspec(dllexport) // 注意这两个不一样哦
#else
#define Calculate_EXPORTS __declspec(dllimport)
#endif
extern "C" Calculate_EXPORTS int Add(int numberA, int numberB);
extern "C" Calculate_EXPORTS int Subtract(int numberA, int numberB);
extern "C" Calculate_EXPORTS int Multiplication(int numberA, int numberB);
extern "C" Calculate_EXPORTS int Divided(int numberA, int numberB);
class CaculateData
{
public:
CaculateData();
~CaculateData();
};
源文件CaculateData.cpp
#include "CaculateData.h"
#include <iostream>
CaculateData::CaculateData()
{
}
CaculateData::~CaculateData()
{
}
Calculate_EXPORTS int Add(int numberA, int numberB)
{
return numberA + numberB;
}
Calculate_EXPORTS int Subtract(int numberA, int numberB)
{
return numberA - numberB;
}
Calculate_EXPORTS int Multiplication(int numberA, int numberB)
{
return numberA * numberB;
}
Calculate_EXPORTS int Divided(int numberA, int numberB)
{
if (numberB == 0) {
std::cout << "除数不能为空" << std::endl;
}
return numberA / numberB;
}
创建CLR中间项目
- 命名为CliDLL
- 添加引用,注意这里应该添加项目引用,而不是浏览,不然后面会调用不到,提示【未能加载文件或程序集“DMC3000, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”或它的某一个依赖项。试图加载格式不正确的程序】
- 配置CliDLL为64位,然后生成动态库
- 增加头文件InvokeCon.h
#pragma once
#include "C:\Users\dell\source\repos\TestingInvoking\Caculate2\CaculateData.h"
public ref class InvokeCon
{
public:
InvokeCon();
int AddCli(int a, int b);
int SubCli(int a, int b);
int MulCli(int a, int b);
int DivCli(int a, int b);
};
- 增加源文件InvokeCon.cpp
#include "InvokeCon.h"
InvokeCon::InvokeCon() {}
int InvokeCon::AddCli(int a, int b) {
return Add(a, b);
}
int InvokeCon::SubCli(int a, int b) {
return Subtract(a, b);
}
int InvokeCon::MulCli(int a, int b) {
return Multiplication(a, b);
}
int InvokeCon::DivCli(int a, int b) {
return Divided(a, b);
}
添加C#控制台项目进行调用
-
创建项目
-
添加依赖项目,注意是项目依赖,别点击浏览引入
-
在控制台项目的csproj文件中 标签中增加如下内容(为了生成exe文件的时候能够和上面两个dll的生成路径在同一个文件夹下,不然调用不到)
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
4. 添加测试代码
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
InvokeCon invokeCon = new InvokeCon();
int sum = invokeCon.AddCli(2, 3);
Console.WriteLine("sum ==" + sum);
Console.WriteLine("Hello World!");
Console.ReadKey();
}
}
}
- 结果展示
注意事项
- 确保vs可以自定义宏
- 确保通过添加项目引用进行添加
- 确保通过两个dll和你的最终的c#客户端生成在同一个文件夹下
遇到的异常
-
严重性 代码 说明 项目 文件 行 禁止显示状态
错误 LNK2019 无法解析的外部符号 _main,该符号在函数 “int __cdecl invoke_main(void)” (?invoke_main@@YAHXZ) 中被引用 Caculate C:\Users\dell\source\repos\TestingInvoking\Caculate\MSVCRTD.lib(exe_main.obj) 1 -
未能加载文件或程序集“DMC3000, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”或它的某一个依赖项。试图加载格式不正确的程序。