对于某些跨平台程序,这也就意味着只能在windows下使用了

不过最近.Net开源或许以后可以跨平台

之前花了一些时间研究COM方式调用,太繁琐不推荐。 COM方式调用总结

后来尝试使用CLR C++,虽然可以用.Net的接口直接载入,但他只是一层C++的皮,最终没能运用在实际项目中。

最后使用MS提供的CLR API接口,完成调用 MSDN CLR接口介绍

=======================================================

有几个注意点:

1.官方一直强调的签名格式static int pwzMethodName (String pwzArgument),并非某个C#特性,而是函数格式必须是带一个string参数返回int型。否则在调用时会报找不到方法。

2.ExecuteInDefaultAppDomain中,dll路径支持相对路径格式,"xx.dll"是可以被识别的。

3.GetRuntime方法获得的.Net版本号,需要去c:/windows/Microsoft.NET下找,64位对应Framework64,普通版对应Framework。如果目标机器没有该文件夹,说明对应版本的.net未安装。那么程序就会报错。版本号第三位数字似乎是死的,应该都是统一的发行版。

4.在创建测试项目时,需要点掉预编译头选项,否则会出现许多莫名其妙的错误。

5.需要在管理员权限下使用

6.类可以是静态类或者非静态,但函数必须是静态函数

参考代码摘自github:

https://github.com/entice/client/blob/42f388d68b1954ef244c379560eeb4867ae80b7e/Loader/Loader/DllMain.cpp

具体上代码

C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Text; namespace ClassLibrary1
{
public class Class1
{
public static int EntryPoint(string arg)
{
File.AppendAllText("C:/xx.txt", "qweqwe");
return ;
}
}
}

C++

//Reference From GitHub entice:https://github.com/entice/client/blob/42f388d68b1954ef244c379560eeb4867ae80b7e/Loader/Loader/DllMain.cpp

#include <Windows.h>
#include <stdio.h>
#include <iostream>
#include <mscoree.h>
#include <metahost.h>
#include <assert.h> #pragma comment(lib, "mscoree.lib") #define BUFFER_SIZE 500
#include "stdafx.h" void StartTheDotNetRuntime(LPCWSTR runtimeVersion, LPCWSTR dllPath, LPCWSTR startClass, LPCWSTR startMethod, LPCWSTR startArgument)
{
ICLRMetaHost *pMetaHost = NULL;
ICLRMetaHostPolicy *pMetaHostPolicy = NULL;
ICLRDebugging *pCLRDebugging = NULL; CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost);
CLRCreateInstance(CLSID_CLRMetaHostPolicy, IID_ICLRMetaHostPolicy, (LPVOID*)&pMetaHostPolicy);
CLRCreateInstance(CLSID_CLRDebugging, IID_ICLRDebugging, (LPVOID*)&pCLRDebugging); DWORD dwVersion = ;
DWORD dwImageVersion = ;
ICLRRuntimeInfo *pRuntimeInfo;
HRESULT result;
result = pMetaHost->GetRuntime(runtimeVersion, IID_ICLRRuntimeInfo, (LPVOID*)&pRuntimeInfo);
assert(SUCCEEDED(result)); ICLRRuntimeHost * pRuntimeHost = NULL;
result = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&pRuntimeHost);
assert(SUCCEEDED(result)); result = pRuntimeHost->Start();
assert(SUCCEEDED(result)); DWORD dwRetCode = ;
result = pRuntimeHost->ExecuteInDefaultAppDomain(dllPath, startClass, startMethod, startArgument, &dwRetCode);
assert(SUCCEEDED(result));
pRuntimeHost->Stop();
pRuntimeHost->Release();
pRuntimeInfo->Release();
pCLRDebugging->Release();
pMetaHostPolicy->Release();
pMetaHost->Release();
} void Loader()
{
wchar_t* runtimeVersionSpace = new wchar_t[BUFFER_SIZE];
wchar_t* dllPathSpace = new wchar_t[BUFFER_SIZE];
wchar_t* currentDir = new wchar_t[BUFFER_SIZE]; GetCurrentDirectoryW(BUFFER_SIZE, currentDir); StartTheDotNetRuntime(L"v4.0.30319", L"ClassLibrary1.dll", L"ClassLibrary1.Class1", L"EntryPoint", L""); free(runtimeVersionSpace);
free(dllPathSpace);
free(currentDir);
} int _tmain(int argc, _TCHAR* argv[])
{
HANDLE handle = CreateThread(NULL, , (LPTHREAD_START_ROUTINE)Loader, NULL, , NULL); for (size_t i = ; i < ; i++)
{
Sleep();
} TerminateThread(handle, ); return ;
}

然后把c#生成的dll,放到c++的build目录下,再以管理员权限执行即可。

最后会在c盘根目录下创建一个xx.txt文件。说明调用C#成功

通过CLR API实现C++调用C#代码交互的更多相关文章

  1. 如何实现 javascript “同步”调用 app 代码

    在 App 混合开发中,app 层向 js 层提供接口有两种方式,一种是同步接口,一种一异步接口(不清楚什么是同步的请看这里的讨论).为了保证 web 流畅,大部分时候,我们应该使用异步接口,但是某些 ...

  2. ArcGIS API for Silverlight 调用GP服务加载等值线图层

    原文:ArcGIS API for Silverlight 调用GP服务加载等值线图层 第二篇.Silverlight客户端调用GP服务 利用ArcGIS API for Silverlight实现G ...

  3. ArcGIS API for Silverlight 调用GP服务准备---GP模型建立、发布、测试

    原文:ArcGIS API for Silverlight 调用GP服务准备---GP模型建立.发布.测试 第一篇.GP降雨量等值线建模.发布及测试 在水利.气象等行业中,要在WebGIS中实现空间分 ...

  4. android 编译调用C代码

    博客地址:www.zalezone.cn 前言 需求来源 这几天帮别人做一个简单的androidclient,也没什么功能,主要就是调用C代码来对手机的Wifi网络进行设置.于是也就引出了技术难点所在 ...

  5. 如何在Java中调用Python代码

    有时候,我们会碰到这样的问题:与A同学合作写代码,A同学只会写Python,而不会Java, 而你只会写Java并不擅长Python,并且发现难以用Java来重写对方的代码,这时,就不得不想方设法“调 ...

  6. 在Winform混合式框架中整合外部API接口的调用

    在我们常规的业务处理中,一般内部处理的接口多数都是以数据库相关的,基于混合式开发的Winform开发框架,虽然在客户端调用的时候,一般选择也是基于Web API的调用,不过后端我们可能不仅仅是针对我们 ...

  7. Windows API方式直接调用C#的DLL,支持多音字转拼音、Gzip解压缩、公式计算(VBA、C++、VB、Delphi甚至java都可以)

    原始链接 https://www.cnblogs.com/Charltsing/p/DllExport.html 这两年,我在VBA应用方面一直有几大痛点:1.多音字转拼音:2.64位下的GZIP解压 ...

  8. python 调用 java代码

    一.JPype简述 1.JPype是什么? JPype是一个能够让 python 代码方便地调用 Java 代码的工具,从而克服了 python 在某些领域(如服务器端编程)中的不足. 2.JPype ...

  9. Golang 调用 Python 代码

    go 中的 cgo 模块可以让 go 无缝调用 c 或者 c++ 的代码,而 python 本身就是个 c 库,自然也可以由 cgo 直接调用,前提是指定正确的编译条件,如 Python.h 头文件( ...

随机推荐

  1. 【GISER&&Painter】Chapter01:WebGL渲染初体验

    基于上一篇OpenGL的渲染原理,这两周又陆续接触了一些关于WebGL绘图的一些内容,因为刚入门,很多东西又很晦涩,所以特意花了小半天的时间整理了一下,特此记录. 零  画一个多边形吧! 把一个多边形 ...

  2. 3DPrint ABS和PLA代码比较

    PLA ABS

  3. Power Desginer系列02【转载】

    在概念模型中主要有以下几个操作和设置的对象:实体(Entity).实体属性 (Attribute).实体标识(Identifiers).关系(Relationship).继承(Inheritance) ...

  4. Orchard运用 - 整合Disqus评论插件

    评论对于博客系统那是必须具备的一个功能,Orchard本身也默认实现了评论模块,你可以集成到其他内容,比如博客随笔,不过觉得有点寒碜,样式有点呆板.幸运的是,你可以简单集成第三方评论插件,比如Disq ...

  5. linux 网络设备驱动

    linux 网络驱动 谨以此文纪念过往的岁月 一.前言在linux中网络驱动也是一个大头,如何去理解网络驱动是作为一个linux驱动工程师必备的技能.不过同样的设备,在不同人的手中会有不同的效果,其原 ...

  6. TZOJ 1072: 编辑距离(动态规划)

    1072: 编辑距离 时间限制(普通/Java):1000MS/10000MS     内存限制:65536KByte 总提交: 917            測试通过:275 描写叙述 如果字符串的 ...

  7. 10分钟,利用canvas画一个小的loading界面

    首先利用定义下canvas得样式 <canvas width="1024" height="720" id="canvas" styl ...

  8. iOS buttonWithType:101 苹果私有api

    无意中发现,有人创建UIButton这样写 UIButton *previousButton = [UIButtonbuttonWithType:101]; 一看原来是私有api UIButton * ...

  9. BNU 26480 Horror List【最短路】

    链接: http://www.bnuoj.com/bnuoj/problem_show.php?pid=26480 http://www.bnuoj.com/bnuoj/contest_show.ph ...

  10. 取球游戏_nyoj_518(博弈-蓝桥杯原题).java

    取球游戏 时间限制: 1000 ms  |  内存限制: 65535 KB 难度: 2   描述 今盒子里有n个小球,A.B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下 ...