C# 将实例回调作为函数指针发送会导致;这";是「;空";在C中#
我正在使用Mono编写一个FileSystemWatcher,但是由于某种原因,我发送到FSEvents库的回调没有包含这个引用,即使回调是一个实例方法,它在回调中也总是空的 知道为什么会这样吗C# 将实例回调作为函数指针发送会导致;这";是「;空";在C中#,c#,macos,mono,filesystemwatcher,fsevents,C#,Macos,Mono,Filesystemwatcher,Fsevents,我正在使用Mono编写一个FileSystemWatcher,但是由于某种原因,我发送到FSEvents库的回调没有包含这个引用,即使回调是一个实例方法,它在回调中也总是空的 知道为什么会这样吗 using System; using System.IO; using System.Collections.Generic; using System.Runtime.InteropServices; using MonoMac.Foundation;
using System;
using System.IO;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using MonoMac.Foundation;
using System.Threading;
using NUnit.Framework;
using System.Text;
namespace Test
{
class MainClass
{
public void Main ()
{
string testFolder = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.MyDocuments), "mono-test");
if (Directory.Exists (testFolder)) {
Directory.Delete (testFolder, true);
}
Directory.CreateDirectory (testFolder);
IntPtr path = CFStringCreateWithCString (IntPtr.Zero, testFolder, 0);
IntPtr paths = CFArrayCreate (IntPtr.Zero, new IntPtr [1] { path }, 1, IntPtr.Zero);
IntPtr stream = FSEventStreamCreate (IntPtr.Zero, this.Callback, IntPtr.Zero, paths, FSEventStreamEventIdSinceNow, 0, FSEventStreamCreateFlags.WatchRoot | FSEventStreamCreateFlags.FileEvents);
CFRelease (paths);
CFRelease (path);
Thread runLoop = new Thread (delegate() {
FSEventStreamScheduleWithRunLoop (stream, CFRunLoopGetCurrent (), kCFRunLoopDefaultMode);
FSEventStreamStart (stream);
CFRunLoopRun ();
});
runLoop.Name = "FSEventStream";
runLoop.Start ();
Thread.Sleep (3000);
string file1 = Path.Combine (testFolder, "file1.txt");
//Thread.Sleep(1000);
using (System.IO.File.Create(file1)) {
}
//Thread.Sleep(1000);
System.IO.File.WriteAllText (file1, "file1");
//Thread.Sleep(1000);
System.IO.File.Delete (file1);
}
public static void Main (string[] args)
{
new MainClass().Main();
}
private static IDictionary<IntPtr, MainClass> thisDict = new Dictionary<IntPtr, MainClass>();
private void Callback (IntPtr streamRef, IntPtr clientCallBackInfo, int numEvents, IntPtr eventPaths, IntPtr eventFlags, IntPtr eventIds)
{
MainClass thisObj;
if (this != null) {
thisDict.Add(streamRef, this);
thisObj = this;
} else {
thisObj = thisDict[streamRef];
}
Console.WriteLine("\n{0}", this != null ? "this is not null" : "this is null");
Console.WriteLine("{0}\n", thisObj != null ? "thisObj is not null" : "thisObj is null");
string[] paths = new string[numEvents];
UInt32[] flags = new UInt32[numEvents];
UInt64[] ids = new UInt64[numEvents];
unsafe
{
char** eventPathsPointer = (char**) eventPaths.ToPointer();
uint* eventFlagsPointer = (uint*) eventFlags.ToPointer();
ulong* eventIdsPointer = (ulong*) eventIds.ToPointer();
for (int i = 0; i < numEvents; i++)
{
paths[i] = Marshal.PtrToStringAuto(new IntPtr(eventPathsPointer[i]));
flags[i] = eventFlagsPointer[i];
ids[i] = eventIdsPointer[i];
}
}
Console.WriteLine("Number of events: {0}", numEvents);
for (int i = 0; i < numEvents; i++)
{
Console.WriteLine("{0} {1:x8} {2}", ids[i], flags[i], paths[i]);
Console.WriteLine("Modified: {0:x8}", (flags[i] & (uint) FSEventStreamEventFlagItem.Modified));
Console.WriteLine("Created: {0:x8}", (flags[i] & (uint) FSEventStreamEventFlagItem.Created));
Console.WriteLine("Removed: {0:x8}", (flags[i] & (uint) FSEventStreamEventFlagItem.Removed));
Console.WriteLine("Renamed: {0:x8}", (flags[i] & (uint) FSEventStreamEventFlagItem.Renamed));
Console.WriteLine();
}
}
[DllImport ("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")]
extern static IntPtr CFStringCreateWithCString (IntPtr allocator, string value, int encoding);
[DllImport ("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")]
extern static IntPtr CFArrayCreate (IntPtr allocator, IntPtr [] values, int numValues, IntPtr callBacks);
[DllImport ("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")]
extern static IntPtr CFArrayGetValueAtIndex(IntPtr array, int index);
[DllImport ("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")]
extern static void CFRelease(IntPtr cf);
[DllImport ("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")]
extern static IntPtr CFRunLoopGetCurrent ();
[DllImport ("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")]
extern static IntPtr CFRunLoopGetMain();
[DllImport ("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")]
extern static void CFRunLoopRun ();
[DllImport ("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")]
extern static int CFRunLoopRunInMode (IntPtr mode, double seconds, int returnAfterSourceHandled);
delegate void FSEventStreamCallback (IntPtr streamRef, IntPtr clientCallBackInfo, int numEvents, IntPtr eventPaths, IntPtr eventFlags, IntPtr eventIds);
[DllImport ("/System/Library/Frameworks/CoreServices.framework/CoreServices")]
extern static IntPtr FSEventStreamCreate (IntPtr allocator, FSEventStreamCallback callback, IntPtr context, IntPtr pathsToWatch, ulong sinceWhen, double latency, FSEventStreamCreateFlags flags);
[DllImport ("/System/Library/Frameworks/CoreServices.framework/CoreServices")]
extern static int FSEventStreamStart (IntPtr streamRef);
[DllImport ("/System/Library/Frameworks/CoreServices.framework/CoreServices")]
extern static void FSEventStreamStop (IntPtr streamRef);
[DllImport ("/System/Library/Frameworks/CoreServices.framework/CoreServices")]
extern static void FSEventStreamRelease (IntPtr streamRef);
[DllImport ("/System/Library/Frameworks/CoreServices.framework/CoreServices")]
extern static void FSEventStreamScheduleWithRunLoop (IntPtr streamRef, IntPtr runLoop, IntPtr runLoopMode);
[DllImport ("/System/Library/Frameworks/CoreServices.framework/CoreServices")]
extern static void FSEventStreamUnscheduleFromRunLoop (IntPtr streamRef, IntPtr runLoop, IntPtr runLoopMode);
const ulong FSEventStreamEventIdSinceNow = ulong.MaxValue;
private static IntPtr kCFRunLoopDefaultMode = CFStringCreateWithCString(IntPtr.Zero, "kCFRunLoopDefaultMode", 0);
[Flags()]
enum FSEventStreamCreateFlags : uint {
None = 0x00000000,
UseCFTypes = 0x00000001,
NoDefer = 0x00000002,
WatchRoot = 0x00000004,
IgnoreSelf = 0x00000008,
FileEvents = 0x00000010
}
[Flags()]
enum FSEventStreamEventFlag : uint {
None = 0x00000000,
MustScanSubDirs = 0x00000001,
UserDropped = 0x00000002,
KernelDropped = 0x00000004,
EventIdsWrapped = 0x00000008,
HistoryDone = 0x00000010,
RootChanged = 0x00000020,
FlagMount = 0x00000040,
Unmount = 0x00000080
}
[Flags()]
enum FSEventStreamEventFlagItem : uint {
Created = 0x00000100,
Removed = 0x00000200,
InodeMetaMod = 0x00000400,
Renamed = 0x00000800,
Modified = 0x00001000,
FinderInfoMod = 0x00002000,
ChangeOwner = 0x00004000,
XattrMod = 0x00008000,
IsFile = 0x00010000,
IsDir = 0x00020000,
IsSymlink = 0x00040000
}
}
}
使用系统;
使用System.IO;
使用System.Collections.Generic;
使用System.Runtime.InteropServices;
使用MONAC;基础;
使用系统线程;
使用NUnit.Framework;
使用系统文本;
名称空间测试
{
类主类
{
公用空干管()
{
string testFolder=Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),“mono-test”);
if(Directory.Exists(testFolder)){
Delete(testFolder,true);
}
Directory.CreateDirectory(testFolder);
IntPtr path=CFStringCreateWithCString(IntPtr.Zero,testFolder,0);
IntPtr path=CFArrayCreate(IntPtr.Zero,newintptr[1]{path},1,IntPtr.Zero);
IntPtr stream=FSEventStreamCreate(IntPtr.Zero,this.Callback,IntPtr.Zero,path,fseventstreamventidsincenow,0,FSEventStreamCreateFlags.WatchRoot | FSEventStreamCreateFlags.FileEvents);
CFRelease(路径);
CFRelease(path);
线程runLoop=新线程(委托(){
FSEventStreamScheduleWithRunLoop(stream,CFRunLoopGetCurrent(),kCFRunLoopDefaultMode);
FSEventStreamStart(流);
CFRunLoopRun();
});
runLoop.Name=“FSEventStream”;
Start();
睡眠(3000);
字符串file1=Path.Combine(testFolder,“file1.txt”);
//睡眠(1000);
使用(System.IO.File.Create(file1)){
}
//睡眠(1000);
System.IO.File.writealText(文件1,“文件1”);
//睡眠(1000);
System.IO.File.Delete(file1);
}
公共静态void Main(字符串[]args)
{
新的MainClass().Main();
}
私有静态IDictionary thisDict=new Dictionary();
私有无效回调(IntPtr streamRef、IntPtr clientCallBackInfo、intnumevents、IntPtr eventpath、IntPtr eventFlags、IntPtr eventid)
{
主类thisObj;
如果(此!=null){
thisDict.Add(streamRef,this);
thisObj=这个;
}否则{
thisObj=thisDict[streamRef];
}
Console.WriteLine(“\n{0}”,this!=null?“this not null”:“this is null”);
Console.WriteLine(“{0}\n”,thisObj!=null?”thisObj不为null:“thisObj为null”);
字符串[]路径=新字符串[numEvents];
UInt32[]标志=新的UInt32[numEvents];
UInt64[]ids=新UInt64[numEvents];
不安全的
{
char**eventPathsPointer=(char**)eventPath.ToPointer();
uint*eventFlagsPointer=(uint*)eventFlags.ToPointer();
ulong*eventIdsPointer=(ulong*)eventIds.ToPointer();
对于(int i=0;i