gpt4 book ai didi

c# - 是否可以调用 R 统计函数来优化 C# 函数

转载 作者:太空狗 更新时间:2023-10-29 21:09:24 26 4
gpt4 key购买 nike

我想知道是否可以从 C# 调用 r 统计优化函数(这里我想使用 regnoud),而要优化的函数是用 C# 编写的。我找到了 RDotNet 库,但有了它我无法评估 R 中的 C# 函数。换句话说,问题是 R 在优化时需要评估函数,但他不能这样做,因为函数在 C# 代码中。

是否有任何解决方案,例如使用 .dll 或其他库?
谢谢。

最佳答案

在使用有点复杂的方法之前,我已经这样做了,但它有效!

首先,您需要创建一个包含您的函数的 C# DLL。您可以在 visual studio 中通过在创建新项目时选择“类库”作为选项来执行此操作。 .cs 文件中的代码应如下所示

namespace MyNamespace
{
//expose an interface with functions to be called from R
public interface MyInterface
{
string MyFunction(string name);
}

//create a class that implements the above interface
public class MyClass : MyInterface
{
public string MyFunction(string name)
{
return "Hello " + name;
}
}

}

现在编译您的项目,您将获得一个 C# DLL。此 DLL 是一个托管 DLL,它不同于 native C/C++ DLL。它不能直接从非 .Net 语言中使用,因此需要作为 COM 对象公开。您可以通过以下两种方式之一执行此操作

  1. 在 Visual Studio 中,您可以转到项目属性,单击“应用程序”选项卡下的“程序集信息”按钮,然后选中“使程序集 COM 可见”复选框。
  2. 或者,您可以使用 .net 安装文件夹中的 regasm.exe 将 DLL 注册为 COM 组件。这是描述此过程的链接。 http://msdn.microsoft.com/en-us/library/tzat5yw6(v=vs.71).aspx .命令通常是“regasm myTest.dll/tlb:myTest.tlb”

COM 注册过程现在将在与您的 DLL 相同的文件夹中创建一个 .tlb 文件。保留此 .tlb 文件。我们将在下一步中需要它

下一步是创建一个可以调用 COM DLL 的 C++ DLL。此步骤是必需的,因为 R 可以直接调用 C++ DLL 但不能直接调用 COM(如果我错了请纠正我,如果您知道从 R 调用 COM 的更好方法,请跳过此步骤)。 dllmain.cpp 中的 C++ DLL 代码如下所示(确保滚动查看完整代码)

#include "stdafx.h"
#include <iostream>

//import the .tlb file create by COM registration

#import "path_to_Dll\MyDll.tlb" named_guids raw_interfaces_only

void _cdecl MyCPPFunction(char ** strName)
{
//Initialize COM
HRESULT hr = CoInitialize(NULL);

//create COM interface pointer
MyNamespace::MyInterfacePtr myPtr;

//create instance of COM class using the interface pointer
HRESULT hr2 = myPtr.CreateInstance(MyNamespace::CLSID_MyClass);

//create variable to hold output from COM.
BSTR output;

//call the COM function
myPtr->MyFunction(_bstr_t(strName[0]), &output);

//convert the returned BSTR from .net into char*
int length = (int) SysStringLen(output);
char *tempBuffer;
tempBuffer = (char *) malloc(1 + length);
WideCharToMultibyte(CP_ACP, 0, output, -1, tempBuffer, length, NULL, NULL);
tempBuffer[length] = '\0';

//release interface
myPtr->Release();

//uninitialize COM
if(hr == S_OK)
CoUninitialize();

//set output in input for returning to R (this is weird but the only way I could make it work)
strName[0] = tempBuffer;
}

现在编译您的项目,您将获得一个 C++ DLL。我们快到了!不要放弃 :)。现在,您有一个作为 COM 对象公开的 C# DLL 和一个可以调用此 COM 对象的 C++ DLL。最后一步是从 R 调用 C++ 函数。这是执行此操作的 R 代码

#load C++ DLL
dyn.load("path_to_C++_DLL")

#call function in C++ DLL and pass in a test name.
# The C++ DLL will in turn call the C# function
output <- .C("MyCPPFunction", as.character("Peter"))

#print output
print(output)

您应该会在 R 控制台中看到 C# 中显示的“Hello Peter”!需要注意一个非常重要的点。

始终使用“任何 CPU”选项编译 COM DLL。始终编​​译 C++ DLL 以匹配您的 R 安装!例如,如果安装了 32 位 R,则确保将 C++ DLL 编译为 32 位 DLL。如果您安装了 64 位 R 并想使用它,请确保将 C++ DLL 编译为 64 位 DLL。祝你好运!

关于c# - 是否可以调用 R 统计函数来优化 C# 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17214741/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com