[英]Invoking C# WPF code in C++
这是我第一次在这里问问题,尽管我经常使用这个网站!
因此,搜索了一段时间后,我发现了这一点: http : //tigerang.blogspot.pt/2008/09/reverse-pinvoke.html
我认为这几乎是我想要做的。 我现在将解释:(PLZ请注意,我是C ++的新手,C#,我来自Java)我在Visual Studio上有一个解决方案,其中有两个项目,即非托管C ++和C#WPF应用程序。 c ++只有一个类,它使用OpenCV进行一些处理。 WPF类连接到图像,检索一些(x,y)点,我必须将它们传递给c ++。 之后,我将从WPF端调用C ++函数,从中获取结果。
所以我现在的问题是,我想通过一个点列表(列表),但是我无法适应我所遇到的情况的示例,因此我发现了很多相关的文档(或者我太新了而且我不知道如何找到/使用它)。
示例代码:C#
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct Ponto
{
public double x;
public double y;
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate List<Ponto> CallBackDelegate();
public class ManagedClass
{
private CallBackDelegate _delegate;
public List<Ponto> vectorp;
public ManagedClass()
{
_delegate = new CallBackDelegate(this.Foo);
}
public CallBackDelegate GetDelegate()
{
return _delegate;
}
public List<Ponto> Foo()
{
//do shit
Ponto p1 = new Ponto();
p1.x = 10;
p1.y = 2;
Ponto p2 = new Ponto();
p2.x = 5;
p2.y = 7;
Ponto p3 = new Ponto();
p3.x = 3;
p3.y = 8;
vectorp.Add(p1);
vectorp.Add(p2);
vectorp.Add(p3);
return vectorp;
}
}
示例代码C ++;
#include <iostream>
#pragma once
#include <windows.h>
#include <list>
#define INTEROPBRIDGE_API __declspec(dllexport)
INTEROPBRIDGE_API void fnInteropBridge(list<Ponto> data) //IM GETTING ERRORS HERE
{
ManagedLib::ManagedClass^ c = gcnew ManagedLib::ManagedClass();
IntPtr p = Marshal::GetFunctionPointerForDelegate(c->GetDelegate());
NativeToManaged funcPointer = (NativeToManaged) p.ToPointer();
// invoke the delegate
funcPointer(data);
}
// data structure for the callback function
struct Ponto
{
double x;
double y;
};
// callback function prototype
typedef void (*NativeToManaged)(list<Ponto> data);
using namespace std;
void main()
{
cout << "Hello World!" << endl;
cout << "Welcome to C++ Programming" << endl;
}
您的C ++代码无法正常工作,因为System.Collections.Generic.List与C ++的std :: list完全不同。
如果您的C ++代码是托管的(当前是托管的),则可以直接引用C#类。 不需要函数指针。
但是,如果您真的想从非托管C ++中使用C#代码,则最简单的方法是通过COM。 关于C#代码,您唯一需要更改的就是更改ManagedClass.Foo以返回一个数组而不是一个List,因为List对COM不可见,还要为该类型添加几个属性并为该类添加一个接口实现:
[ComVisible(true)]
[Guid("2EF06BCB-A25B-41AD-B233-33A956DBEB69")]
public struct Ponto
{
public double x;
public double y;
public Ponto(double x, double y)
{
this.x = x;
this.y = y;
}
}
[ComVisible(true)]
[Guid("EB9258F5-DCFB-4F91-8342-5A05EB17557D")]
public interface IManagedClass
{
Ponto[] Foo();
}
[ComVisible(true)]
[Guid("11B23AD7-F79E-45D7-BC87-89F0DBC8B83F")]
[ClassInterface(ClassInterfaceType.None)]
public class ManagedClass : IManagedClass
{
private List<Ponto> points;
public ManagedClass()
{
points = new List<Ponto>();
points.Add(new Ponto(1.0, 1.0));
points.Add(new Ponto(2.0, 2.0));
points.Add(new Ponto(3.0, 3.0));
}
public Ponto[] Foo()
{
return points.ToArray();
}
}
生成项目,以管理员权限启动Visual Studio命令提示符,并使用如下命令为程序集导出类型库并注册它:
重排ManagedAssembly.dll /tlb:ManagedAssembly.tlb / codebase
C ++代码会像这样消耗它:
#import "ManagedAssembly.tlb"
#include <iostream>
using namespace ManagedAssembly;
using namespace std;
int main()
{
::CoInitialize(NULL);
{
IManagedClassPtr pManagedClass(__uuidof(ManagedClass));
SAFEARRAY* psa = pManagedClass->Foo();
Ponto* pPoints = (Ponto*)psa->pvData;
for (int i = 0; i < 3; ++i)
cout << pPoints[i].x << " " << pPoints[i].y << endl;
}
::CoUninitialize();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.