9

我一直在努力使这项工作有一段时间了……阅读了很多帖子,但没有一个可以解决此问题。

我正在使用佳能 SDK 连接到 EOS 550D。我正在运行 win7 64bit 和 Visual Studio c# 2010。

我一步一步做的是:

--> 0 初始化 SDK

 err = EDSDK.EdsInitializeSDK();

--> 1 获取相机列表

 err = EDSDK.EdsGetCameraList(out cameraList);

--> 2 获取子数

 err = EDSDK.EdsGetChildCount(cameraList, out cameraCount);

--> 3 如果有孩子,获取第一个孩子

  err = EDSDK.EdsGetChildAtIndex(cameraList, 0, out cameraDev);

--> 4 打开一个会话

err = EDSDK.EdsOpenSession(cameraDev);

--> 5 告诉sdk在本地保存图片

IntPtr saveTo = (IntPtr)EDSDK.EdsSaveTo.Host;
err = EDSDK.EdsSetPropertyData(cameraDev, EDSDK.PropID_SaveTo, 0, 4, saveTo);

--> 6 设置主机可用容量

 EDSDK.EdsCapacity capacity = new EDSDK.EdsCapacity();

 if (err == EDSDK.EDS_ERR_OK)
 {
     capacity.NumberOfFreeClusters = 0x7FFFFFFF;
     capacity.BytesPerSector = 0x1000;
     capacity.Reset = 1;
     err = EDSDK.EdsSetCapacity(cameraDev, capacity);
 }

--> 7 注册状态事件处理器

err = EDSDK.EdsSetCameraStateEventHandler(cameraDev, EDSDK.StateEvent_All, stateEventHandler,   new IntPtr(0));

--> 8 注册对象事件处理程序

 EDSDK.EdsObjectEventHandler edsObjectEventHandler = new EDSDK.EdsObjectEventHandler(objectEventHandler);
               err = EDSDK.EdsSetObjectEventHandler(cameraDev, EDSDK.ObjectEvent_All, edsObjectEventHandler, IntPtr.Zero);

……

这样做时我没有收到任何错误,一切似乎都很好。

这是我的处理程序

 private uint objectEventHandler(uint inEvent, IntPtr inRef, IntPtr inContext)
    {
        Console.WriteLine("HALLLOOOOOOOOOO");
        switch (inEvent)
        {
            case EDSDK.ObjectEvent_DirItemCreated:
                //this.invokeNewItemCreatedEvent(new NewItemCreatedEventArgs(getCapturedItem(inRef)));
                Console.WriteLine("Directory Item Created");
                break;
            case EDSDK.ObjectEvent_DirItemRequestTransfer:
                Console.WriteLine("Directory Item Requested Transfer");
                break;
            default:
                Console.WriteLine(String.Format("ObjectEventHandler: event {0}, ref {1}", inEvent.ToString("X"), inRef.ToString()));
                break;
        }

        return 0x0;
    }








    public uint stateEventHandler(uint inEvent, uint inParameter, IntPtr inContext)
    {
        Console.WriteLine("stateEventHandler " + inEvent);
        switch (inEvent)
        {
            case EDSDK.StateEvent_JobStatusChanged:
                Console.WriteLine(String.Format("There are objects waiting to be transferred.  Job status {0}", inParameter));
                break;

            case EDSDK.StateEvent_ShutDownTimerUpdate:
                if (inParameter != 0)
                    Console.WriteLine(String.Format("shutdown timer update: {0}", inParameter));
                break;

            case EDSDK.ObjectEvent_DirItemRequestTransfer:
                //WHAT I NEED!!!
                Console.WriteLine("Hallo DirItemRequestTransfer");
                //DownloadImage(obj);
                break;


            default:
                Console.WriteLine(String.Format("StateEventHandler: event {0}, parameter {1}", inEvent, inParameter));
                break;
        }
        return 0;
    }

...

所以现在我的问题是没有一个处理程序被调用过。不知道为什么,我在网上搜索了一段时间,尝试了不同的方法但没有得到回调......

这是我调用拍照命令的方法:

 public void takePic()
    {
        if (cameraOpened)
        {
           Console.WriteLine( "taking a shot");

            err = EDSDK.EdsSendCommand(cameraDev, EDSDK.CameraCommand_TakePicture, 0);
            if (err != EDSDK.EDS_ERR_OK)
                Console.WriteLine("TakeCommand Error: " + err.ToString());

            Console.WriteLine("Finished taking a shot");

        }
    }

也许有人知道我可以尝试做什么?

提前致谢!

最好的问候,托拜厄斯

4

4 回答 4

10

我知道 SDK 文档说回调函数将在另一个线程中执行,但对我来说,在 Windows 下使用 SDK 2.11,回调总是发生在主线程上,并且似乎是通过 Windows 消息发送的。这意味着如果您没有消息泵,您将不会收到回调。如果您的应用程序是 C# GUI 应用程序,您应该有一个消息泵,但如果它是一个控制台应用程序,您可能没有,所以在发送 TakePicture 命令后尝试手动泵送消息。您可以使用 Application.Run 但您需要在某处调用 Application.Exit 否则您的消息循环将永远不会退出(例如,您可以在从相机下载图片后调用它)。

于 2013-04-01T14:49:07.997 回答
1

我使用 SDK 的 C++ 版本已经有几个月了。

快速扫描后,您的代码似乎一切正常。我不确定此示例中的 C# 垃圾收集/范围,但您希望确保您的处理程序在设置它们后仍然“周围”。

此外,对于最后的 EdsContext 参数,我使用指向包含类的指针而不是零指针。

err = EDSDK.EdsSetObjectEventHandler(cameraDev, EDSDK.ObjectEvent_All, edsObjectEventHandler, IntPtr.Zero);

如果你不需要在一个类中包含你的事件处理程序,这可能不是问题,但你的应用程序中的多线程可能会咬你。从 EDSDK 手册:

通过回调函数指定要传递的应用程序信息。可以传递您的应用程序所需的任何数据。在多线程环境中,回调函数由专门针对事件的线程执行。适当地使用它,如指定 this 指针以将数据传递给 UI 线程。如果不需要,请指定一个 NULL 指针。

您还可以尝试添加一个 handlePropertyEvent 处理程序,该处理程序应该触发白平衡的变化/切换到实时取景等。

于 2012-12-08T09:11:11.610 回答
0

您订阅对象事件的方式并没有真正订阅任何内容。我就是这样做的,而且效果很好:

event EDSDK.EdsObjectEventHandler SDKObjectEvent;

void Init(IntPtr cameraDev)
{
    SDKObjectEvent += new EDSDK.EdsObjectEventHandler(objectEventHandler);
    EDSDK.EdsSetObjectEventHandler(cameraDev, EDSDK.ObjectEvent_All, SDKObjectEvent, IntPtr.Zero);
}

EdsStateEventHandler、EdsPropertyEventHandler 和 EdsCameraAddedHandler 的原理相同(有点不同,但仍然有事件 EdsProgressCallback)

亲切的问候

于 2014-04-10T13:13:55.697 回答
0

我正在使用佳能 SDK 连接到 EOS 550D。我正在运行 win7 64bit 和 Visual Studio c# 2010。

您的问题就在那里:Canon SDK 是为 X86 编译的。不要再看了!您必须更改目标架构。

于 2013-06-26T20:22:28.283 回答