我遇到了锁定Windows工作站的示例:
using System.Runtime.InteropServices;
...
[DllImport("user32.dll", SetLastError = true)]
static extern bool LockWorkStation();
...
if (!LockWorkStation())
throw new Win32Exception(Marshal.GetLastWin32Error()); // or any other thing
Run Code Online (Sandbox Code Playgroud)
这个片段有一个纯粹的托管替代方案吗?即,没有P-Invoke.
我有一个从C#应用程序调用的非托管C++ DLL,我试图让C#应用程序捕获所有异常,以便在由于非托管异常导致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
Run Code Online (Sandbox Code Playgroud)
C++ - Test.cpp
#include <iostream>
#include <vector>
using namespace std;
void ProcessBadCall()
{
vector<int> myValues;
int a = myValues[1];
cout << a << endl;
}
Run Code Online (Sandbox Code Playgroud)
C# - Program.cs
class Program
{
[DllImport("Test.dll", EntryPoint="ProcessBadCall")]
static extern void ProcessBadCall();
static void Main(string[] args)
{
try
{
ProcessBadCall();
}
catch (SEHException ex)
{
Console.WriteLine("SEH Exception: {0}", ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("Exception: {0}", …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个WPF窗口WindowStyle="None"(用于自定义按钮,没有标题),无法调整大小.设置ResizeMode以NoResize删除我想要保留的空气边界.
我可以设置最小/最大尺寸属性并完成它,除了:
所以,我有一个简单的方案,让我99%的方式:
public class BorderedWindowNoResize : Window
{
[DllImport( "DwmApi.dll" )]
public static extern int DwmExtendFrameIntoClientArea(
IntPtr hwnd,
ref MARGINS pMarInset );
[DllImport( "user32.dll", CharSet = CharSet.Auto )]
public static extern IntPtr DefWindowProc(
IntPtr hWnd,
int msg,
IntPtr wParam,
IntPtr lParam );
public BorderedWindowNoResize()
{
Loaded += BorderedWindowNoResize_Loaded;
}
private void BorderedWindowNoResize_Loaded( object sender, RoutedEventArgs e )
{
IntPtr mainWindowPtr = new WindowInteropHelper( this ).Handle;
HwndSource mainWindowSrc = HwndSource.FromHwnd( mainWindowPtr ); …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个NTFS Junction.从cmd行我可以使用sysinternals中的junction.exe工具执行此操作.结点的DIR cmd输出如下所示:
Volume in drive C has no label.
Volume Serial Number is C8BC-2EBD
Directory of c:\users\cheeso\Documents
03/22/2009 09:45 PM <JUNCTION> My Music [\??\c:\users\cheeso\Music]
05/11/2007 05:42 PM <DIR> My Received Files
03/22/2009 09:46 PM <JUNCTION> my videos [\??\c:\users\cheeso\Videos]
Run Code Online (Sandbox Code Playgroud)
我在某地读过Junctions是Symbolic Links的子集.
所以我尝试使用CreateSymbolicLink创建一个Junction.当我这样做时,我实际上得到了一个符号链接,而不是一个连接点.
09/09/2009 11:50 AM <SYMLINKD> newLink [.\]
Run Code Online (Sandbox Code Playgroud)
还有CreateHardLink.那里的文档说交汇点(又名"重新分析点")是硬链接的子集.但我似乎无法接受这项工作.它完成但没有创建硬链接或联结.
我正在使用.NET/C#,导入如下所示:
[Interop.DllImport("kernel32.dll", EntryPoint="CreateSymbolicLinkW", CharSet=Interop.CharSet.Unicode)]
public static extern int CreateSymbolicLink(string lpSymlinkFileName, string lpTargetFileName, int dwFlags);
[Interop.DllImport("kernel32.dll", EntryPoint="CreateHardLinkW", CharSet=Interop.CharSet.Unicode)]
public static extern bool CreateHardLink(string lpFileName, …Run Code Online (Sandbox Code Playgroud) 对不起,下面是详细的介绍.我需要知道P/Invoke内部人员的洞察力比我更好.
这是我如何编组包含从C到C#的函数指针的结构.我想知道这是否是最干净和/或最有效的方式.
我正在使用C编码的本机DLL连接,它提供以下入口点:
void* getInterface(int id);
Run Code Online (Sandbox Code Playgroud)
您必须传递getInterface(int)以下枚举值之一:
enum INTERFACES
{
FOO,
BAR
};
Run Code Online (Sandbox Code Playgroud)
它返回一个指向包含函数指针的结构的指针,如:
typedef struct IFOO
{
void (*method1)(void* self, int a, float b);
void (*method2)(void* self, int a, float b, int c);
} IFoo;
Run Code Online (Sandbox Code Playgroud)
以下是您在C中使用它的方式:
IFoo* interface = (IFoo*)getInterface(FOO);
interface->method1(obj, 0, 1.0f); // where obj is an instance of an object
// implementing the IFoo interface.
Run Code Online (Sandbox Code Playgroud)
在C#中,我有一个使用P/Invoke Library映射getInterface(int)入口点的类.
class Library
{
[DllImport("MyDLL"), EntryPoint="getInterface", CallingConvention=CallingConvention.Cdecl)]
public static extern IntPtr GetInterface(int id);
};
Run Code Online (Sandbox Code Playgroud)
然后我定义了:
struct …Run Code Online (Sandbox Code Playgroud) 请考虑以下场景:我正在运行我的应用程序,在执行期间,必须运行另一个进程,并且只有在第二个进程完成内部特定初始化之后,我的第一个进程才能继续.例如:
...
// Process1 code does various initializations here
Process.Start("Process2.exe");
// Wait until Process2 finishes its initialization and only then continue (Process2 doesn't exit)
...
Run Code Online (Sandbox Code Playgroud)
我看到几个选项:
我很高兴听到你对这个案子的意见.
谢谢!
首先让我说看看我在整个论坛和网络上的许多链接中找到了固定{},Marshal.AllocHGlobal()和GCHandle.Alloc()的使用说明.但是,我还没有找到关于何时使用Marshal类与GCHandle类(使用和不使用fixed {})的简明解释.
我正在使用第三方.NET库,它在"Buffer"类中有一个名为Readline()的方法.该手册显示了以下函数原型:
bool ReadLine(int x1,int y1,int x2,int y2,System.IntPtr bufData,out int numRead);
描述bufData,说明:...内存区域的字节数必须大于或等于行长度乘以BytesPerPixel属性返回的值.
现在,后来在他们的用户手册,做给访问该缓冲区(我已经调整了我的具体的例子一点点)的例子:
// Create an array large enough to hold one line from buffer
int size = 640;
byte[] dataLine = new byte[size * 2]; // 2 bytes per pixel
// Pin the array to avoid Garbage collector moving it
GCHandle dataLineHandle = GCHandle.Alloc(dataLine, GCHandleType.Pinned);
IntPtr dataLineAddress = dataLineHandle.AddrOfPinnedObject();
Run Code Online (Sandbox Code Playgroud)
我可以按照上面的"示例"代码:
// Read one line of buffer data
success = buffer.ReadLine(0, 0, 639, 0, …Run Code Online (Sandbox Code Playgroud) 我有一个用C++实现的非常大的系统,我需要与之交互.该系统有一个非常大的API,许多C++ DLL.这些DLL导出C++类,而不是一个漂亮的C风格API.我需要从一个新的C#项目中使用它们.
据我所知,.NET有三种与本机软件交互的方式:
所以我理解它的方式,我有三种方法:
我的问题:
首先,我想知道为什么.NET不允许我"按原样"使用C++类?我假设这是一个内存管理问题.如果是的话,我更愿意编写终结器,并实现IDisposable.据我所知,C++类只是非常奇特的结构,并且由于P/Invoke支持结构,以及将结构作为第一个参数的函数,为什么不支持类呢?
其次,假设我真的很懒,而且它很无聊,乏味,工作,使用这些DLL的最佳方法是什么?直接从C#调用它们的可能性是最好的.如果没有,那么我会喜欢自动工具来制作包装纸.此外,DLL可能会稍微改变,但仍然,id而不是强制手动重写包装器.
对于一个非常好的答案,特别是在第一部分,或一个很好的自动工具,我会奖励赏金......
谢谢
我有一个unsafe byte*指向已知长度的本机字节数组.我该怎么把它转换成byte[]?
一unsafe sbyte*到零结尾的本地字符串指针可以被转换成一个C#string容易,因为有一个转换构造函数用于此目的,但我不能找到一个简单的方法来转换byte*到byte[].
首先是一个背景问题:
一般来说,int和之间有什么区别IntPtr?我的猜测是它是一个实际的对象,而不是像int或是一个值byte.假设是真的:
所以他们不一样.然而,我看到手柄代表两者.
Control.Handleint(或uint):PInvoke可以设置为返回一个int并且它可以正常工作:
[DllImport("coredll.dll", SetLastError = true)]
public static extern int GetForegroundWindow();
private string GetActiveWindow()
{
const int nChars = 256;
int handle = 0;
StringBuilder Buff = new StringBuilder(nChars);
handle = CoreDLL.GetForegroundWindow();
if (CoreDLL.GetWindowText(handle, Buff, nChars) > 0)
{
return Buff.ToString();
}
return "";
}
Run Code Online (Sandbox Code Playgroud)那么,intvs IntPtr?手柄有问题吗?你能用吗?