我有一个用c#编写的程序(让我们称它为ValidationChecker)。此ValidationChecker需要只能由python或c++使用的OMPL库。因此,生成了一个编译为.exe的c++解决方案。
ValidationChecker启动可执行文件,并打开其自身与.exe之间的TCP通信。之后,ValidationChecker通过tcp通信向exe发送一些启动数据,exe从启动数据中生成一些数据。在创建一个新数据包后的某些过程中,此数据由exe转换,然后发送到ValidationChecker以检查此新生成的数据是否有效。因此,exe将等待,直到ValidationCecker发回确认此数据有效或无效的消息。这是一个循环,直到exe生成足够的有效数据包。
我现在的问题是:从创建新的数据包到ValidationChecker发送确认的整个循环需要120ms。必须创建的数据包的数量在100到3000之间变化。首先,我做了一些分析,注意到转换数据的过程需要60-70ms,所以我优化了这个过程,现在这个过程只需要1-2ms。(首先我做了一些嵌入python,现在我调用dll )我认为这将加速我的循环。但是整个循环仍然需要120ms,我想知道为什么?因此,我对持续时间的测量表明,数据转换现在更快了,但将数据发送到c#的通信速度变慢了,几乎与减少的百分比相当。
我考虑过将c++解决方案直接集成到ValidationChecker中,但我不太确定这是否真的可行。我通过pinvoke、com对象和从我的c++解决方案生成一个动态链接库来读取一些东西。但是,这是否真的加快了c#程序和c++计算之间的通信速度,或者可能比实际的通信速度慢?另一个问题是,需要交换数据,而不仅仅是通过调用函数并返回某个值。有一个c#函数必须调用c#函数进行验证检查,并且需要一个返回值来确认此数据是否有效。
如此多的文本,我希望你能理解我的想法,并能帮助我更快地解决问题。因为我不太确定是否可以在dll中调用c#函数。如果此解决方案比以前使用tcp的解决方案更快。
发布于 2015-08-31 17:58:26
因为您没有添加任何代码,所以我将给您一个简单的示例,说明如何使用P/Invoke来调用C#中的非托管库。P/invoke比TCP连接快得多,P/invoke的唯一开销是必须完成的参数转换。
在本例中,您可以看到[return: MarshalAs(UnmanagedType.Bool)],它指示运行时将返回值转换为布尔值。这是获取正确值所必需的。这也可以用于方法参数。
using System;
using System.Runtime.InteropServices;
class BeepSample
{
[DllImport("kernel32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool Beep(uint dwFreq, uint dwDuration);
static void Main()
{
Console.WriteLine("Testing PC speaker...");
var success = Beep(200, 5);
Console.WriteLine("Testing complete. " + success);
}发布于 2015-08-31 20:32:25
实现这一点的“内置”方法(不必从C#中P/Export )是从C++ DLL中导出一个“入口点”。问题是C#不能直接使用C++,所以你需要一个干净的C接口(你不能在方法签名中使用任何C++的东西)。
在C++中,您可以执行类似以下内容的操作:
extern "C"
{
struct PackageRequest
{
LPWSTR SomeString;
int32_t SomeInt;
};
struct PackageResult
{
LPWSTR SomeString;
int32_t SomeInt;
};
__declspec(dllexport) HRESULT DoSomething(PackageRequest& request, PackageResult& response)
{
//...
}
}然后在C#中:
static class NativeMethods
{
public struct PackageRequest
{
[MarshalAs(UnmanagedType.LPWStr)]
public StringBuilder SomeString;
public int SomeInt;
}
public struct PackageReponse
{
[MarshalAs(UnmanagedType.LPWStr)]
public StringBuilder SomeString;
public int SomeInt;
}
[DllImport("MyDll.dll")]
private static extern int DoSomething(ref PackageRequest req, out PackageReponse resp);
public static PackageReponse DoSomething(PackageRequest req)
{
PackageReponse resp;
var rc = DoSomething(ref req, out resp);
if (rc != 0)
throw new Exception("...");
return resp;
}
}https://stackoverflow.com/questions/32307806
复制相似问题