鉴于此C API声明如何将其导入C#?
int _stdcall z4ctyget(CITY_REC *, void *);
Run Code Online (Sandbox Code Playgroud)
我已经能够做到这一点:
[DllImport(@"zip4_w32.dll",
CallingConvention = CallingConvention.StdCall,
EntryPoint = "z4ctygetSTD",
ExactSpelling = false)]
private extern static int z4ctygetSTD(ref CITY_REC args, void * ptr);
Run Code Online (Sandbox Code Playgroud)
当然在C#中,"void*"无法编译.
一些谷歌搜索表明它应该被翻译为"对象".这似乎应该工作.但其他人表示"Void*在C/C++术语中被称为函数指针,在C#术语中是一个委托".在这里,这并不是很有意义,因为它会委托给谁?通过谷歌搜索找到的其他API的类似调用使用相应API中的其他函数.但是在这个API中没有其他调用是有意义的.
该调用的文档显示了一个示例:
z4ctyget(&city, “00000”);
Run Code Online (Sandbox Code Playgroud)
这似乎表明甚至可以传递静态值.
它将使用object代替void*进行编译.我不知道这是否正确,我没有机会对其进行测试(许可问题).
使用PInvoke时会发生什么异常,或者方法返回值处理的所有错误都是由开发人员根据需要检查和引发异常?
我认为委托实例可以与函数实例互换.
请使用以下代码:
delegate int AddDelegate(int a, int b);
AddDelegate DelegateInstance;
public void DoStuff()
{
//I can call this without a delegate "instance":
MethodThatTakesAdd(Add);
//I can also call it WITH a delegate "instance"
DelegateInstance = Add;
MethodThatTakesAdd(DelegateInstance);
}
public int Add(int a, int b)
{
return a + b;
}
public void MethodThatTakesAdd(AddDelegate addFunction)
{
Console.WriteLine(addFunction(1, 2).ToString());
}
Run Code Online (Sandbox Code Playgroud)
两种方式称它为APPEAR是等价的,如果你只使用C#,你将永远不会看到差异(至少我还没有达到这一点).但是,我最近是一个回调到这个托管代码的非托管代码,它们的处理方式不同.例如,在一个场景中,如果我直接将函数用作回调(即使我的对象实例被保留),我也会得到错误"对垃圾收集的委托进行了回调".使用"委托实例"可以解决问题.
那里有人知道有什么区别吗?
这是我的ClickMouse()函数的代码:
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
private const long MOUSEEVENTF_LEFTDOWN = 0x02;
private const long MOUSEEVENTF_LEFTUP = 0x04;
private const long MOUSEEVENTF_RIGHTDOWN = 0x08;
private const long MOUSEEVENTF_RIGHTUP = 0x10;
private void ClickMouse()
{
long X = Cursor.Position.X;
long Y = Cursor.Position.Y;
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, X, Y, 0, 0);
}
Run Code Online (Sandbox Code Playgroud)
出于某种原因,当我的程序来到此代码时,它会抛出此错误消息:
检测到PInvokeStackImbalance消息:调用PInvoke函数'WindowsFormsApplication1!WindowsFormsApplication1.Form1 :: mouse_event'使堆栈失去平衡.这很可能是因为托管PInvoke签名与非托管目标签名不匹配.检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配.
请帮忙?
我有一个具有cdecl回调的ac库.我如何从c#中使用这些.
一切似乎都说他们必须是stdcall回调
要清楚:
delegate int del();
[dllimport("mylib.dll",CallingConvention=CallingConvention.Cdecl)]
public static extern int funcwithcallback(del foo);
Run Code Online (Sandbox Code Playgroud)
其中del必须被称为cdecl-wise
好吧,我在C#中使用oracle的ContentAccess库,库是用C语言编写的.
我使用库的一些功能从不同的文件中提取文本.c库使用函数指针(Delegates)的异步通信.我有1个类和1个结构来使用这些函数,结构被称为BaseIO并包含指向我在C#中的代码读取文件的函数指针.一切都很好,直到cli移动我的类,我得到一个MemoryAccessException.
这是类,结构和函数签名:
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate DAERR CloseDelegate(IntPtr hfile);
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate DAERR ReadDelegate(IntPtr hfile, IntPtr dataPtr, UInt32 size, IntPtr count);
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate DAERR WriteDelegate(IntPtr hfile, IntPtr dataPtr, int size, IntPtr count);
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate DAERR SeekDelegate(IntPtr hfile, int wFrom, int dwOffset);
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate DAERR TellDelegate(IntPtr hfile, IntPtr dwOffset);
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate DAERR GetInfoDelegate(IntPtr hfile, UInt32 dwInfoId, IntPtr pInfo);
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate DAERR Seek64Delegate(IntPtr hfile, ushort wFrom, Int64 dwOffset);
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate DAERR Tell64Delegate(IntPtr hfile, Int64 dwOffset);
struct …Run Code Online (Sandbox Code Playgroud) 我有一个错误的第三方DLL文件,在执行一段时间后,开始抛出访问冲突异常.当发生这种情况时,我想重新加载该DLL文件.我怎么做?
我只是想做一些托管/非托管互操作.为了获得扩展的错误信息,我决定注册dll提供的日志回调:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public unsafe delegate void LogCallback(void* arg1,int level,byte* fmt);
Run Code Online (Sandbox Code Playgroud)
这个定义有效,但我得到的字符串如"格式%s探测大小=%d和得分=%d".我尝试添加__arglist关键字,但代表不允许这样做.
嗯,这对我来说并不那么引人注目,但我只是好奇,有人可以在C#中获得varargs参数.我知道我可以使用c ++进行互操作.所以:有没有办法在C#中做到这一点,合理的efford?
编辑:对于那些仍然没有得到它的人:我没有导入 varargs函数但是将它作为回调导出,然后将其称为我的本机代码.我一次只能指定一个 - >只能进行一次重载而__arglist不起作用.
我用c#Windows Forms制作了一个屏幕键盘.我使用Sendkeys.Send()函数发送击键.除了这封信之外的所有信件都i很好.当我i打开Microsoft Word时按下键盘上的字母时,它会发送Ctrl+ Alt+ I并打开打印对话框.在Notepad ++中也是如此.但是当我尝试输入记事本时,它工作正常.
在我的代码中,我发送键,SendKeys.Send(value);其中value是按下按钮的文本.我使用以下代码获取文本:
string s = ((Button)sender).Text;
Run Code Online (Sandbox Code Playgroud)
关于它为什么不能正常工作的任何评论?
编辑:我只用一个按钮创建了一个新的Windows窗体项目,整个代码如下.还是行不通.任何想法将不胜感激.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
SendKeys.Send("i");
}
// Prevent form being focused
const int WS_EX_NOACTIVATE = 0x8000000;
protected override CreateParams CreateParams
{
get
{
CreateParams ret = base.CreateParams;
ret.ExStyle |= WS_EX_NOACTIVATE;
return ret;
}
}
}
Run Code Online (Sandbox Code Playgroud)
被覆盖的功能是防止表单被聚焦.这样我就可以将键击发送到具有焦点的其他应用程序.
我想在 OSX 中提取 EDID 信息?
看起来它存储在IORegistry. 有没有办法使用当前的monomac库访问它?我可以用标准interop来做还是我需要写一个自定义shim?
看起来ioreg命令行也可以获取IODisplayEDID 属性,但似乎没有一种简单的方法来获取设备的缩写列表。