Tag: pinvoke

在C#中编组char **

我正在接受带有char**代码(即指向字符串的指针): int DoSomething(Whatever* handle, char** error); 基本上,它需要处理其状态,如果出现问题,它会返回错误代码和可选的错误消息(内存分配在外部,并使用第二个函数释放。这部分我已经指出:))。 但是,我不确定如何处理C#。 我目前所拥有的: [DllImport(“mydll.dll”, CallingConvention = CallingConvention.Cdecl)] private static unsafe extern int DoSomething(IntPtr handle, byte** error); public static unsafe int DoSomething(IntPtr handle, out string error) { byte* buff; int ret = DoSomething(handle, &buff); if(buff != 0) { // ??? } else { error = “”; } return ret; } […]

C#:根据平台访问32位/ 64位DLL

我们使用来自C#应用程序的自编写32位C ++ DLL。 现在我们注意到当C#应用程序在64位系统上运行时,会自动使用64位运行时,当然也无法从64位运行时访问32位DLL。 我的问题是:有没有办法使用32位DLL? 如果没有,如果我创建了64位版本的DLL,是否可以轻松地让应用程序选择哪一个进行P / Invoke? 我想在C#中创建两个辅助类:一个从32位DLL导入函数,一个从64位DLL导入,然后创建一个包装类,每个导入的函数都有一个函数调用32位导入器或者64位导入程序取决于操作系统的“bittyness”。 那会有用吗? 或者还有另一种简单的方法吗?

C#没有捕获非托管C ++ DLL的未处理exception

我有一个从C#应用程序调用的非托管C ++ dll,我正在尝试使用C#应用程序捕获所有exception,以便在由于非托管exception导致dll失败的情况下,用户将获得半合适的错误消息(C#app是一个实现它自己的http处理程序的Web服务)。 我遇到的问题是并非所有类型都被捕获。 因此,如果我创建以下内容并执行C#应用程序,则dll会抛出错误并终止整个应用程序。 有任何想法吗? 这是在VS2005中使用.Net framework v2创建的 C ++ – Test.h #ifndef INC_TEST_H #define INC_TEST_H extern “C” __declspec(dllexport) void ProcessBadCall(); #endif C ++ – Test.cpp #include #include using namespace std; void ProcessBadCall() { vector myValues; int a = myValues[1]; cout << a << endl; } C# – Program.cs class Program { [DllImport(“Test.dll”, EntryPoint=”ProcessBadCall”)] […]

CreateProcessAsUser在活动会话中创建窗口

我正在使用Windows服务中的CreateProcessAsUser( 我们可以保持主题并假设我有充分的理由这样做 )。 与其他人在这里问的问题相反,我在我的活动终端会话(会话1)中获得了一个窗口,而不是与服务(会话0)相同的会话 – 这是不可取的。 我挪用了斯科特艾伦的代码 ; 并想出以下内容。 值得注意的变化是“恢复自我”,“CREATE_NO_WINDOW”和命令行参数支持。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security; using System.Runtime.InteropServices; using System.Diagnostics; using System.Security.Principal; using System.ComponentModel; using System.IO; namespace SourceCode.Runtime.ChildProcessService { [SuppressUnmanagedCodeSecurity] class NativeMethods { [StructLayout(LayoutKind.Sequential)] public struct STARTUPINFO { public Int32 cb; public string lpReserved; public string lpDesktop; public string lpTitle; public […]

在密封的类上实现IDisposable

我不认为此问题曾经被问过。 我对在密封类上实现IDisposable的最佳方法感到困惑 – 特别是一个不从基类inheritance的密封类。 (也就是说,这是一个“纯密封的类”,这是我的术语。) 也许你们有些人同意我的看法,实施IDisposable的指导方针非常混乱。 也就是说,我想知道我打算实现IDisposable是足够和安全的。 我正在做一些通过Marshal.AllocHGlobal分配IntPtr P / Invoke代码,当然,我想干净地处理我创建的非托管内存。 所以我在考虑这样的事情 using System.Runtime.InteropServices; [StructLayout(LayoutKind.Sequential)] public sealed class MemBlock : IDisposable { IntPtr ptr; int length; MemBlock(int size) { ptr = Marshal.AllocHGlobal(size); length = size; } public void Dispose() { if (ptr != IntPtr.Zero) { Marshal.FreeHGlobal(ptr); ptr = IntPtr.Zero; GC.SuppressFinalize(this); } } ~MemBlock() { Dispose(); […]

如何将数据从托管程序集流式传输到本机库并再次返回?

如何将数据(文本)从托管程序集流式传输到本机库并将数据(文本)流式传输回托管程序集? 具体来说,我想在.NET端公开某种类型的System.IO.Stream ,并且( 最重要的是 )在本机端公开一个FILE * 。 本机方法的签名应该是: FILE * foo(FILE * bar); 本机p / invoke调用的包装签名应该是: CustomStream foo(CustomStream bar); 我不想在本机端使用回调方法 (一个用于获取更多数据,一个用于设置更多数据)。 我想在本机端使用FILE * – 以及对其进行操作的所有相关方法,例如fprintf 。 我不想要任何磁盘I / O. 这需要是内存中的操作。 我完全控制托管程序集和本机库。 该解决方案必须与.NET 2.0一起使用 我愿意创建任何类型的托管或非托管填充层来实现这一目标。 “显而易见”的解决方案是使用STDIN和STDOUT并启动子进程 – 但是我不想要一个单独的进程。 此外,我尝试重定向本机库的STDIN和STDOUT流,而这些流不是Windows上的控制台应用程序,但它的失败程度有些惊人(并且有很多头脑冲击)。 基于这个问题: 在C#Windows服务上重定向stdout + stderr我试图修改方法(至少)解决问题的一半“响应”流 – 但是没有FileStream (因为我想要一些类似于MemoryStream东西) )。 但是, FileStream是唯一公开合适的低级流句柄的流类型。 否则,我已经陷入困境,而且我现在正在考虑我需要深入研究并提出我自己的手动本地托管流实现,但实际上并不知道从哪里开始。 解 最后! 我在这里发布了一个完整的示例项目: http://pastebin.com/jcjHdnwz 这适用于.NET 3.5并使用AnonymousPipeServerStream […]

在C ++和C#ByRef之间传递字节数组会引发AccessViolationException

我试图创建一个Win32 DLL公开一些在C#中调用的函数,如下所示 __declspec(dllexport) int GetData(unsigned char* *data, int* size) { try { int tlen = 3; unsigned char* tchr = new unsigned char[5]; tchr[0] = ‘a’; tchr[1] = ‘b’; tchr[2] = ‘c’; *size = tlen; *data = tchr; return 1; } catch (char *p) { return 0; } } 在C#方面 [DllImport(“MyDll.dll”)] static extern int GetData(ref […]

有没有办法调试从C#DllImport调用的c ++ dll?

我想知道是否有任何方法可以在VS 2010中调试从C#PInvoke调用的c ++ dll。我试图将项目附加到c#应用程序但是它没有工作 – 没有停在断点处。 我还尝试在C ++项目中使用OutputDebugString记录任何内容,但没有使用PInvoke调用打印。 尽管存在这些问题,但实际function运行良好。 任何建议将被认真考虑。

P /调用Mono上动态加载的库

我正在编写一个使用一些非托管代码的跨平台.NET库。 在我的类的静态构造函数中,检测平台并从嵌入式资源中提取适当的非托管库并保存到临时目录,类似于另一个stackoverflow应答中给出的代码。 因此,当它不在PATH中时可以找到它,我在将它保存到临时文件后显式加载它。 在Windows上,这适用于kernel32.dll的LoadLibrary 。 我正在尝试使用Linux上的dlopen进行相同的操作,但是稍后在加载P / Invoke方法时会遇到DllNotFoundException 。 我已经validation库“libindexfile.so”已成功保存到临时目录,并且对dlopen的调用成功。 我深入研究了单声道源代码 ,试图弄清楚发生了什么,我认为可能归结为后续调用dlopen是否会重用以前加载的库。 (当然,假设我天真地通过单声道来源得出了正确的结论)。 这是我正在尝试做的形状: // actual function that we’re going to p/invoke to [DllImport(“indexfile”)] private static extern IntPtr openIndex(string pathname); const int RTLD_NOW = 2; // for dlopen’s flags const int RTLD_GLOBAL = 8; // its okay to have imports for the wrong platforms here […]

在“托管到原生过渡”期间究竟发生了什么?

我知道CLR需要在某些情况下进行编组,但是我要说: using System.Runtime.InteropServices; using System.Security; [SuppressUnmanagedCodeSecurity] static class Program { [DllImport(“kernel32.dll”, SetLastError = false)] static extern int GetVersion(); static void Main() { for (; ; ) GetVersion(); } } 当我用调试器进入这个程序时,我总是看到: 鉴于没有需要完成的编组(对吗?),有人可以解释一下这种“托管到原生的过渡”中实际发生了什么,以及为什么有必要?