Objective c 如何从不使用';看不到Obj-C变量?

Objective c 如何从不使用';看不到Obj-C变量?,objective-c,c,macos,multi-touch,Objective C,C,Macos,Multi Touch,我正在尝试使用一些代码来显示macbook pro中的原始轨迹板数据,比如FingerMgmt应用程序。不幸的是,似乎没有人知道FingerMgmt的来源。不过,我确实找到了其他一些类似的源代码。我可以像这样记录我想看到的数据: int callback(int device, Finger *data, int nFingers, double timestamp, int frame) { for (int i=0; i<nFingers; i++) { Finger *f

我正在尝试使用一些代码来显示macbook pro中的原始轨迹板数据,比如FingerMgmt应用程序。不幸的是,似乎没有人知道FingerMgmt的来源。不过,我确实找到了其他一些类似的源代码。我可以像这样记录我想看到的数据:

int callback(int device, Finger *data, int nFingers, double timestamp, int frame) {


for (int i=0; i<nFingers; i++) {
    Finger *f = &data[i];
    NSLog(@"Frame %7d: Angle %6.2f, ellipse %6.3f x%6.3f; "
          "position (%6.3f,%6.3f) vel (%6.3f,%6.3f) "
          "ID %d, state %d [%d %d?] size %6.3f, %6.3f?\n",
          f->frame,
          f->angle * 90 / atan2(1,0),
          f->majorAxis,
          f->minorAxis,
          f->normalized.pos.x,
          f->normalized.pos.y,
          f->normalized.vel.x,
          f->normalized.vel.y,
          f->identifier, f->state, f->foo3, f->foo4,
          f->size, f->unk2);
    //todo-get data from raw C to obj-C variable
}


    return 0;
int回调(int设备、Finger*数据、int文件、双时间戳、int帧){
对于(int i=0;iframe,
f->角度*90/atan2(1,0),
f->majorAxis,
f->minorAxis,
f->normalized.pos.x,
f->标准化位置y,
f->normalized.vel.x,
f->normalized.vel.y,
f->identifier,f->state,f->foo3,f->foo4,
f->size,f->unk2);
//todo从原始C获取数据到obj-C变量
}
返回0;
}

但是,每当我尝试将任何数据存储到Obj-c字符串或变量时,c代码都不会将变量视为已声明。因此,我无法写入Obj-C中的任何文本字段或图形显示,也无法将数据存储到Obj-C可以访问的变量中

基本上,我需要一种从回调中写入Obj-C变量或对象的方法

顺便说一句,前一段时间我在iPhone应用程序中遇到了一个非常类似的问题,我最终通过在C代码中声明应用程序委托并这样写入或读取变量来解决了这个问题-

me.delegate=(id <UIApplicationDelegate,UITabBarControllerDelegate>)[[UIApplication sharedApplication] delegate];//allows access to the delegate within C function
me.delegate.number0=5;//writes to this variable in the delegate
me.delegate=(id)[[UIApplication sharedApplication]delegate]//允许访问C函数中的委托
me.delegate.number0=5//在委托中写入此变量

由于某种原因,我似乎无法适应我目前的情况。我总是得到“me”未声明的错误。

Objective-C方法可以访问实例变量,因为它自动传递了一个带有公共名称的隐藏参数
self
——任何对实例变量的引用,比如
fred
,都会被编译器转换为字段引用,比如
self->fred
(以及财产参考的类似翻译)

要让C函数
回调
访问任何对象的字段(或调用对象的方法),您需要向函数传递对该对象的引用。两种简单的方法:

  • 向函数添加参数。许多C回调协议都包含一个通用的“用户定义”值,该值作为
    void*
    传递,如果调用其中一个值,则将对象引用作为该值传递,并在C函数中将其转换回正确的Objective-C类型
  • 通过全局(或文件静态)变量传递对象,例如
    静态NSSomeType*objectForCallback;
    。当您使用不支持用户定义值的现有C回调协议时,此方法会起作用。但是,共享单个静态变量时,它不是线程安全或可重入安全的
  • 在这两种情况下,如果不使用垃圾收集,请确保对象是
    retain
    'ed

    回应评论 案例1:您将看到声明的C函数,(a)接受回调函数,(b)每次调用时传递给该函数的用户定义值。例如:

    typedef T ...;
    
    T findMatching(T *buffer,                           // an array of T to search
                   size_t count,                        // number of items in array
                   int (*matcher)(T item, void *user),  // user function for match, 1st arg is item, 2nd user-supplied value
                   void *userValue);                    // user-supplied value to pass to matcher
    
    int myMatcher(T item, void *user)
    {
        NSMutableDictionary *myDictionary = (NSMutableDictionary *)user;
        ...
    }
    
    - (void) someMethod
    {
        NSMutableDictionary *sharedWithC = ...;
        ...
        T found = findMatching(buffer, count, myMatcher, (void *)sharedWithC);
        ...
    }
    
    如果您面临这样的C函数,您可以将(
    retain
    'ed,如果需要)Objective-C对象作为
    userValue
    传递,并将其转换回
    匹配器中的Objective-C类型。例如:

    typedef T ...;
    
    T findMatching(T *buffer,                           // an array of T to search
                   size_t count,                        // number of items in array
                   int (*matcher)(T item, void *user),  // user function for match, 1st arg is item, 2nd user-supplied value
                   void *userValue);                    // user-supplied value to pass to matcher
    
    int myMatcher(T item, void *user)
    {
        NSMutableDictionary *myDictionary = (NSMutableDictionary *)user;
        ...
    }
    
    - (void) someMethod
    {
        NSMutableDictionary *sharedWithC = ...;
        ...
        T found = findMatching(buffer, count, myMatcher, (void *)sharedWithC);
        ...
    }
    
    案例2:Objective-C是C的(超集)。您可以像在C中一样声明全局。例如(很少检查,不是线程安全的):

    针对第二条评论 我猜您正在尝试使用第三方(Google?)代码。该代码定义了一个回调协议-一个C函数类型。您不能仅仅通过添加额外参数来重新定义该C函数类型,并期望第三方代码神奇地处理

    因此,除非您打算更改C,否则可以使用第二种方法-将对Objective-C对象的引用存储在全局中。在您的情况下,这将类似于:

    static MT2AppDelegate *sharedWithCAppDelegateReference;
    
    int callback(...)
    {
        ...
        [sharedWithCAppDelegateReference->L1 setStringValue:@"Hellofff"];
        ...
    }
    
    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
    {
        sharedWithCAppDelegateReference = self; // store so C can pick it up
        ...
        MTRegisterContactFrameCallback(dev, callback);
        ...
    }
    

    但请记住,这不是线程或重入安全的-您实际上是通过全局变量传递函数参数。如果您需要线程/重入安全,您需要更多地参与。

    我对此有点困惑。我认为我的回调不支持任何用户定义的变量,即使它支持,我也不知道如何使用这是我的应用程序代理。我已经尝试了我能想到的一切…至于第二个,我也不太明白-我似乎不能声明一个静态NSVariable。还有,你如何在objective-c中声明一个全局变量?我从来没有这样做过,我总是保留需要“全局”的变量在应用程序委托中,定义一些getter/setter方法。@wayager,不要传递整个应用程序委托,只需在结构中传递所需的数据。好的,仍然没有得到它。抱歉,我现在正在考虑这个问题。我只需要看一次它的运行情况。在这一点上,我只是在void*几乎任何可能工作的地方,而且我真的在飞如果有帮助的话,这是我的应用程序代理。m:这里可能有一些随机的无用代码。这是我的。h:很抱歉,我太笨了,这是当你从随机的互联网教程中学到所有东西时会发生的事!:)非常好用!谢谢如果使其线程安全是重要的,你能把我链接到一些信息或给我一个这样做的指针吗?做了一些研究,因为只有一件事(回调)是混乱的文本字段,它不需要线程安全,不是吗?