我试图理解平台调用服务、组件对象模型等概念,但我发现很难理解什么是什么以及不同的职责所在。我一直在研究包含以下内容的代码:
[DllImport("shell32.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
[return: MarshalAs(UnmanagedType.Interface)]
internal static extern object SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string pszPath, IBindCtx pbc, ref Guid riid);
[ComImport]
[Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IShellItem
Run Code Online (Sandbox Code Playgroud)
据我了解,前者导入一个创建 shell 项的函数,后者导入创建它们所需的类型(接口)。
我不明白的是为什么一个使用 DllImport 而另一个使用 ComImport。它们各自的文档中没有任何内容说明要使用哪种方法,也没有提供 COM 对象的 GUID。我唯一的猜测是,区别因素是前者是一个函数,后者是一个接口。
我使用 Hybridizer 构建了一个程序,用 C# 编写 CUDA 代码并调用函数。该程序可以正常运行,但我注意到设置 GPU 并调用其函数的开销非常高。例如,在 CPU 上运行时需要 3000 个时钟周期的作业需要大约 5000 万个时钟周期来设置 GPU 包装器,然后在 GPU 上运行时需要另外 5000 万个时钟周期。我试图弄清楚这种滞后是否是由于 Hybridizer 本身造成的,或者是从我的 C# 程序调用 GPU 代码时不可避免的。
所以我正在寻找替代方法。我的搜索发现一些提到了 P/invoke 的东西,但我真的找不到关于如何使用它的好指南,而且所有这些线程都有 9 年以上的历史了,所以我不知道它们的信息是否仍然相关。我还发现了一些有关 ManagedCuda 的内容,但似乎不再开发。
我正在尝试公开一个 C 函数,该函数将 UTF-8 字符串传递给 C# (dotnet 5.0)。我收到一条对我来说没有意义的警告。这是使用 fopen(3) 重现它的简单方法:
[DllImport("libc.so.6", CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr fopen([MarshalAs(UnmanagedType.LPUTF8Str)] string pathname, string mode);
Run Code Online (Sandbox Code Playgroud)
Visual Studio 2019 报告警告:
从文档来看,我似乎需要CharSet.Ansi在我的情况下进行设置:
并使用UnmanagedType.LPUTF8Str:
我从文档中误解了什么?
我在非托管C/C++代码(dll)中有一个函数,它返回一个包含char数组的结构.我创建了C#struct来接收调用该函数的返回值.并且调用此函数的uppon得到'System.Runtime.InteropServices.MarshalDirectiveException'
这是C声明:
typedef struct T_SAMPLE_STRUCT {
int num;
char text[20];
} SAMPLE_STRUCT;
SAMPLE_STRUCT sampleFunction( SAMPLE_STRUCT ss );
Run Code Online (Sandbox Code Playgroud)
这是C#声明:
struct SAMPLE_STRUCT
{
public int num;
public string text;
}
class Dllwrapper
{
[DllImport("samplecdll.dll")]
public static extern SAMPLE_STRUCT sampleFunction(SAMPLE_STRUCT ss);
}
Run Code Online (Sandbox Code Playgroud)
我使用1字节ASCII.
有没有人有关于如何做到这一点的提示或解决方案?
我有一个C#应用程序,它使用SendMessage pinvoke方法向应用程序外的各个窗口发送"关闭窗口"消息(WM_CLOSE/16).这很有效,除非有问题的窗口是Windows资源管理器窗口.我没有异常,但窗口没有关闭.
这是签名:
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
internal static extern IntPtr SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
Run Code Online (Sandbox Code Playgroud)
我需要将不同的消息发送到Windows资源管理器窗口吗?或者另一种方法来实现这一目标?
我在C++中有一个带有以下签名的dll.它在c ++中工作;
void Decompress(unsigned char *in,int in_len,unsigned char * out,
unsigned *o_len,int *e);
Run Code Online (Sandbox Code Playgroud)
参数说明
我怎样才能从c#中调用它?
什么是P/Invoke声明?
我有一个C#应用程序,它通过p/invoke使用第三方(闭源)本机DLL.
在其中一些调用期间,DLL将使用operator new/operator new []分配内存,并返回一个用于读取结果的指针.
在分配和返回之后,DLL永远不会释放此内存.如何在C#中执行等效的本机操作符delete/operator delete []?
我有一个C++函数导出为api像这样:
#define WIN322_API __declspec(dllexport)
WIN322_API char* Test(LPSTR str);
WIN322_API char* Test(LPSTR str)
{
return "hello";
}
Run Code Online (Sandbox Code Playgroud)
该函数由.DEF文件正确导出为API,因为我可以在Dependency Walker工具中看到它.现在我有一个C#测试程序:
[DllImport("c:\\win322.dll")]
public static extern string Test([MarshalAs(UnmanagedType.LPStr)] String str);
private void Form1_Load(object sender, EventArgs e)
{
string _str = "0221";
Test(_str); // runtime error here!
}
Run Code Online (Sandbox Code Playgroud)
在调用Test()方法时我得到错误:
"调用PInvoke函数'MyClient!MyClient.Form1 :: Test'使堆栈失衡.这很可能是因为托管PInvoke签名与非托管目标签名不匹配.请检查PInvoke签名的调用约定和参数是否与目标非托管签名."
我尝试了很多其他数据类型和编组,但什么也没得到!请帮助我!
有人可以建议我该如何处理这条消息?
CA1060将P/Invokes移动到NativeMethods类因为它是P/Invoke方法,所以应该在名为NativeMethods,SafeNativeMethods或UnsafeNativeMethods的类中定义'UControl.InternetGetConnectedState(out int,int)'.兆.UControl.xaml.cs 33
码:
namespace Mega
{
/// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
public partial class UControl
{
[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int description, int reservedValue);
Run Code Online (Sandbox Code Playgroud)
谢谢!