我想将一个 C# 对象的引用放入非托管内存 (C),我猜是一个指针 (int),当 C 代码稍后回调到 C# 时,我想从非托管内存中取回引用,所以我可以解决它,并访问该对象。原因是 C 代码控制应该使用哪个对象,没有真正的替代方案。我对 C 代码的控制有限,不能选择 C++/CLI。
问题:这是否可能且安全,如果是,如何?
我能够通过装饰它成功地将引用类型对象从 C# 传递到 C++StructLayout(LayoutKind.Sequential)
C# 中的类:
StructLayout(LayoutKind.Sequential)
public class Point
{
[DataMember]
public double X { get; set; }
[DataMember]
public double Y { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
C++ 中的等价物:
struct Point
{
public:
double x;
double y;
};
Run Code Online (Sandbox Code Playgroud)
C++中的函数体:
extern "C" __declspec(dllexport) void Translate(Point* pt, double dx, double dy)
{
pt->x += dx;
pt->y += dy;
}
Run Code Online (Sandbox Code Playgroud)
以及 C# 中的等效项:
[DllImport("myDll.dll", CallingConvention = CallingConvention.Cdecl)]
public extern static void Translate(Point pt, double dx, double dy);
Run Code Online (Sandbox Code Playgroud)
到目前为止我没有遇到任何问题,当我在接下来的两个函数之间传递这些点的数组时,问题就会发生:
extern "C" __declspec(dllexport) …Run Code Online (Sandbox Code Playgroud) 我在我的应用程序中使用了p/invoke GetSystemTime()方法来获取当前的系统日期时间,但它为此提供了错误的值.
我希望有人能够帮助我解决这个问题,我的应用程序中有以下代码,用于获取 矩形
var windowPosition = NativeMethods.GetWindowRect(this._hwnd);
return new Rect(windowPosition.Left, windowPosition.Top, windowPosition.Width, windowPosition.Height);
Run Code Online (Sandbox Code Playgroud)
我在为自定义窗口编写的一些代码中使用了它,这是在 WPF 应用程序中,该窗口是使用IWindowManager.OpenWindow.
当我运行代码并打开窗口时,我在windowPositionRECT 对象中得到以下值
top = 1466, bottom = 785, left = 26, right = 26, width = 0, height = -681
Run Code Online (Sandbox Code Playgroud)
我看不出代码中有什么问题,最终会在 RECT 中得到这些奇数值,ArgumentException结果我在下一行中得到了一个。
我也尝试过将此窗口作为主应用程序窗口运行,但我遇到了同样的问题,该应用程序正在使用 MVVM 和 Caliburn Micro,尽管我不确定为什么这会产生影响。
根据要求,RECT 结构定义如下:
[StructLayout(LayoutKind.Sequential)]
internal struct RECT
{
public void Offset(int dx, int dy)
{
this.Left += dx;
this.Top += dy;
this.Right += dx;
this.Bottom += dy;
}
public int Left { …Run Code Online (Sandbox Code Playgroud)