我有一些权威的 ANSI 标准 C 代码。这意味着虽然我有源代码,但我不能翻译成另一种语言,也不能修改调用参数,因为这些操作会使权限无效。有 150 多个函数。
我可以进行附带更改,例如将文件名从 .C 更改为 .CPP,以便使用 Visual Studio 2009 的 C++ 编译器进行编译,我已经完成了。还可以添加编译器指令等。如有必要,我还可以通过包装层。
另一个限制是我的公司不希望我在任何 C# 代码中使用 unsafe 关键字。
我需要从 C# 程序中获取这些函数。
典型的 C/C++ 函数如下所示:
double SomeFunction(double a, double[3] vec, double[3][3] mat);
其中数组内容有时输入,有时输出,很少同时输入。
我首先尝试制作一个非托管 DLL(带有标记为 Extern C 的函数)。只有简单参数(int、double)的函数工作正常,但我无法确定如何编码数组。 (其实我确实找到了一些示例代码,但是重复150次非常复杂和不合理。)
然后,我在同一个解决方案中尝试了两个项目,一个使用 C++,另一个使用 C#。在 C++ 项目中,我创建了一个托管函数,它只调用标记为非托管的原始函数。这是非常干净和简单的,再一次,简单的论点工作得很好。但是对于数组,我找不到如何使参数类型在 C# 到 C++ 边界之间匹配:
<i> Argument '2': cannot convert from 'double[]' to 'double*'</i>
(并且如上所述,我不能使用 unsafe 来获取指针)。
当然,我正在尝试做的事情一定是可能的。
获得这些功能的最佳方式是什么?
(使用上述函数的示例代码会非常酷。)
最佳答案
示例 C/C++ 实现:
extern "C" __declspec(dllexport)
double SomeFunction(double a, double vec[3], double mat[3][3]) {
double sum = a;
for (int ix = 0; ix < 3; ++ix) {
sum += vec[ix];
for (int iy = 0; iy < 3; ++iy) {
sum += mat[ix][iy];
}
}
return sum;
}
示例 C# 用法:
private void Form1_Load(object sender, EventArgs e) {
double[] vec = new double[3];
double[,] mat = new double[3, 3];
for (int ix = 0; ix < 3; ++ix) {
vec[ix] = ix;
for (int iy = 0; iy < 3; ++iy) {
mat[ix, iy] = (ix + 1) * iy;
}
}
double sum = SomeFunction(1, vec, mat);
}
[System.Runtime.InteropServices.DllImport("cpptemp8.dll")]
private static extern double SomeFunction(double a, double[] vec, double[,] mat);
关于c# - 从 C# 获取非托管 C++ 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/604470/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge
我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c
我安装了ruby版本管理器,并将RVM安装的ruby实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby。有没有办法让emacs像shell一样尊重ruby的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit