Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Calling C++ Image API from C#

Calling C++ Image API from C#

Scheduled Pinned Locked Moved C#
csharpc++data-structuresjsonperformance
24 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • _ _Erik_

    Ok, it's pretty weird... I am not sure what is going on here. The correct way to import MY_IMAGE type and the function is as I told you before, there is no need of marshaling for any field. You might try a little change, using Marshal.UnsafeAddrOfPinnedArrayElement instead of AddrOfPinnedObject method of GCHandle class, I mean, you first pin the buffers with GCHandle and then set the address in pbuf fields this way:

    img1.pbuf = Marshal.UnsafeAddrOfPinnedArrayElement(buffer1, 0);
    img2.pbuf = Marshal.UnsafeAddrOfPinnedArrayElement(buffer2, 0);

    If it still does not work, you might try allocating the buffers directly in the global heap, with Marshal.AllocHGlobal (remember to free this memory when you don't need it any more), instead of creating them in the managed heap as we did before when instantiated the buffers with new byte[size]. If this works you should then copy the buffers allocated in the global heap to the managed heap with the method Marshal.Copy.

    E Offline
    E Offline
    econner
    wrote on last edited by
    #21

    Erik - Thanks for your help. I have it working now. The reason it was failing after the last step was due to other settings that had to be set on the scanner. The vendor makes a single side and double side scanner. The sample in the documetation does not match the process. I dug around in the C++ sample and found other settings that I was able to specify before scanning the card.

    E 1 Reply Last reply
    0
    • E econner

      Erik - Thanks for your help. I have it working now. The reason it was failing after the last step was due to other settings that had to be set on the scanner. The vendor makes a single side and double side scanner. The sample in the documetation does not match the process. I dug around in the C++ sample and found other settings that I was able to specify before scanning the card.

      E Offline
      E Offline
      econner
      wrote on last edited by
      #22

      One of the functions was not in the documentation and the sample I was using. I found the function when reviewing the header file and the C++ test app code.

      1 Reply Last reply
      0
      • _ _Erik_

        Ok, it's pretty weird... I am not sure what is going on here. The correct way to import MY_IMAGE type and the function is as I told you before, there is no need of marshaling for any field. You might try a little change, using Marshal.UnsafeAddrOfPinnedArrayElement instead of AddrOfPinnedObject method of GCHandle class, I mean, you first pin the buffers with GCHandle and then set the address in pbuf fields this way:

        img1.pbuf = Marshal.UnsafeAddrOfPinnedArrayElement(buffer1, 0);
        img2.pbuf = Marshal.UnsafeAddrOfPinnedArrayElement(buffer2, 0);

        If it still does not work, you might try allocating the buffers directly in the global heap, with Marshal.AllocHGlobal (remember to free this memory when you don't need it any more), instead of creating them in the managed heap as we did before when instantiated the buffers with new byte[size]. If this works you should then copy the buffers allocated in the global heap to the managed heap with the method Marshal.Copy.

        E Offline
        E Offline
        econner
        wrote on last edited by
        #23

        Erik, I wanted to thank you again for the assistance. I was able to confirm that the code require the buffer and pinning/marshaling of the memory and it will not work correctly without the suggestions you provided. I also wanted to let you know what compounded the testing issue with the error was due to incomplete documentation. After getting the process to work, I was able to change certain settings and was able to cause the process to fail. Basically, the image class has to define the height and width to the MAXIMUM allowed image that the scanner can accept. Then the buffer size is set to the max height * max width * single/double scanner mode. Once the scanner returns the image, it adjusts the height and buffer values to be what are read in from the scanner. If the image sizes are specified incorrectly/too small, the API will cause a memory error. For example, the image of the scanned area may be 4" but the scanner's read head is capable of scanning a wider area. So the image width has to be pre-set the maximum width of the read head and not the width of the item that is being scanned. BTW, these maximum values are not specified in the documentation or samples. I actually had to dig thru a C++ sample application and the header files to find these settings. Thanks again.

        _ 1 Reply Last reply
        0
        • E econner

          Erik, I wanted to thank you again for the assistance. I was able to confirm that the code require the buffer and pinning/marshaling of the memory and it will not work correctly without the suggestions you provided. I also wanted to let you know what compounded the testing issue with the error was due to incomplete documentation. After getting the process to work, I was able to change certain settings and was able to cause the process to fail. Basically, the image class has to define the height and width to the MAXIMUM allowed image that the scanner can accept. Then the buffer size is set to the max height * max width * single/double scanner mode. Once the scanner returns the image, it adjusts the height and buffer values to be what are read in from the scanner. If the image sizes are specified incorrectly/too small, the API will cause a memory error. For example, the image of the scanned area may be 4" but the scanner's read head is capable of scanning a wider area. So the image width has to be pre-set the maximum width of the read head and not the width of the item that is being scanned. BTW, these maximum values are not specified in the documentation or samples. I actually had to dig thru a C++ sample application and the header files to find these settings. Thanks again.

          _ Offline
          _ Offline
          _Erik_
          wrote on last edited by
          #24

          You're welcome. I'm glad to know you finally solved it.

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups