473,322 Members | 1,671 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

Pinvoke question: How to structure callback that includes a buffer

We are using a 3rd party API that processes video stream files to update a
data structure in the file. I am writting a C# facade for this API but I am
having a hard time getting it to pass data correctly. Can someone please
check out the approach I am using and give me some advice?

The API is structured where I initialize it by passing in two callback
methods. These methods in my C# code are called by the API to read and write
buffers from the input or output files. When I populate the "get" buffer in
the GetStreamBuf method I should see that same buffer in the subsequent
PutStreamBuf callback, but the PutStreamCallback appears to recieve an empty
buffer, as though the GetStreamBuf didn't really popultate the buffer.
//API Initialization
public delegate Int32 GetStreamBufCallback([In, Out] Byte[] Buf, Int32
buf_len);
public delegate Int32 PutStreamBufCallback([In, Out] Byte[] Buf, Int32
buf_len);

[DllImport("tableprocessor.dll", CharSet = CharSet.Ansi, EntryPoint = "#33",
CallingConvention=CallingConvention.StdCall)]
private static extern int InitProcessor(
GetStreamBufCallback GsCb,
PutStreamBufCallback PsCb,
Boolean enableLogging,
Int32 logLevel,
String logFile
);

//Callback methods
System.IO.FileStream fsInput;
Byte[] sharedGetBuf = new Byte[PACKET_SIZE]; //Allocate buffer
Byte[] sharedPutBuf = new Byte[PACKET_SIZE]; //Allocate buffer

public Int32 GetStreamBuf(Byte[] buf, Int32 bufSize)
{
if (fsInput != null)
{
if (fsInput.Read(sharedGetBuf, 0, bufSize) ==
TpFacade.PACKET_SIZE)
{
buf = sharedGetBuf;
return SUCCESS; //return callback status
to API
}
}
}
public Int32 PutStreamBuf(Byte[] buf, Int32 bufSize)
{
sharedPutBuf = buf;
//...
return SUCCESS; //Success == 0

}
--
Regards,
Tom Allen
Aug 29 '07 #1
3 1722
And the call to initialize the API
if (TpFacade.InitProcessorFacade(GetStreamBuf, PutStreamBuf,
m_EnableLogging, m_LogLevel, apiLogFileString))
{ return; }

Thanks for any help!
--
Regards,
Tom Allen
"Tom Allen" wrote:
We are using a 3rd party API that processes video stream files to update a
data structure in the file. I am writting a C# facade for this API but I am
having a hard time getting it to pass data correctly. Can someone please
check out the approach I am using and give me some advice?

The API is structured where I initialize it by passing in two callback
methods. These methods in my C# code are called by the API to read and write
buffers from the input or output files. When I populate the "get" buffer in
the GetStreamBuf method I should see that same buffer in the subsequent
PutStreamBuf callback, but the PutStreamCallback appears to recieve an empty
buffer, as though the GetStreamBuf didn't really popultate the buffer.
//API Initialization
public delegate Int32 GetStreamBufCallback([In, Out] Byte[] Buf, Int32
buf_len);
public delegate Int32 PutStreamBufCallback([In, Out] Byte[] Buf, Int32
buf_len);

[DllImport("tableprocessor.dll", CharSet = CharSet.Ansi, EntryPoint = "#33",
CallingConvention=CallingConvention.StdCall)]
private static extern int InitProcessor(
GetStreamBufCallback GsCb,
PutStreamBufCallback PsCb,
Boolean enableLogging,
Int32 logLevel,
String logFile
);

//Callback methods
System.IO.FileStream fsInput;
Byte[] sharedGetBuf = new Byte[PACKET_SIZE]; //Allocate buffer
Byte[] sharedPutBuf = new Byte[PACKET_SIZE]; //Allocate buffer

public Int32 GetStreamBuf(Byte[] buf, Int32 bufSize)
{
if (fsInput != null)
{
if (fsInput.Read(sharedGetBuf, 0, bufSize) ==
TpFacade.PACKET_SIZE)
{
buf = sharedGetBuf;
return SUCCESS; //return callback status
to API
}
}
}
public Int32 PutStreamBuf(Byte[] buf, Int32 bufSize)
{
sharedPutBuf = buf;
//...
return SUCCESS; //Success == 0

}
--
Regards,
Tom Allen
Aug 29 '07 #2
Tom,
>//API Initialization
public delegate Int32 GetStreamBufCallback([In, Out] Byte[] Buf, Int32
buf_len);
public delegate Int32 PutStreamBufCallback([In, Out] Byte[] Buf, Int32
buf_len);
The runtime can't know how bit those buffers are unless you tell it.
Try adding the attribute [MarshalAs(UnmanagedType.LPArray,
SizeParamIndex=1)] to the Buf parameters.

public Int32 GetStreamBuf(Byte[] buf, Int32 bufSize)
{
if (fsInput != null)
{
if (fsInput.Read(sharedGetBuf, 0, bufSize) ==
TpFacade.PACKET_SIZE)
{
buf = sharedGetBuf;
Here you're just changing which array the local buf parameter refers
to. It will not change the content of the buffer that is passed to
you. You have to copy the data into buf (or read into it directly)
instead.
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Aug 29 '07 #3
Thanks, Mattias! That helps a lot. I'm not out of the woods, yet, but I'm
on my way... :)
--
Regards,
Tom Allen
"Mattias Sjögren" wrote:
Tom,
//API Initialization
public delegate Int32 GetStreamBufCallback([In, Out] Byte[] Buf, Int32
buf_len);
public delegate Int32 PutStreamBufCallback([In, Out] Byte[] Buf, Int32
buf_len);

The runtime can't know how bit those buffers are unless you tell it.
Try adding the attribute [MarshalAs(UnmanagedType.LPArray,
SizeParamIndex=1)] to the Buf parameters.

public Int32 GetStreamBuf(Byte[] buf, Int32 bufSize)
{
if (fsInput != null)
{
if (fsInput.Read(sharedGetBuf, 0, bufSize) ==
TpFacade.PACKET_SIZE)
{
buf = sharedGetBuf;

Here you're just changing which array the local buf parameter refers
to. It will not change the content of the buffer that is passed to
you. You have to copy the data into buf (or read into it directly)
instead.
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Aug 29 '07 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: vijaya | last post by:
I've a problem with PInvoke.I've to invoke a unmanaged dll fucntion in C# which uses a callback fucntion.Please apologise for this lenghty message and render ur kind help. The original dll...
1
by: edgekaos | last post by:
I want to pass a structure to a unmanaged dll function. Inside this structure there is a pointer to a callback function. Unmanaged code will call this managed function as a callback function. I...
3
by: Michael | last post by:
Hi all, I'm having trouble PInvoking a TCHAR within a struct. I'll paste the specific struct's API definition below. I've tried so many numerous variations. The main Win32 error I get is...
7
by: Rymfax | last post by:
I would really appreciate it if someone could help me figure out what I'm doing wrong trying to PInvoke SetupDiEnumDriverInfo. All the other PInvokes i've done up to this point work fine. Whenver...
2
by: MyCrystalGift | last post by:
Hi, I have an old C++ GUI Application CPPAPP.exe that calls a C DLL library RULE.DLL through a C++ class wrapper LoadRule.CPP. Now I need to call the C DLL RULE.DLL from C# GUI application...
2
by: Subodh | last post by:
Hi All, I want to use a C++ API in a static lib that returns a linked List in C# I am planning to P/Invoke to perform the Interop, I would like to know which way will be better to interop a...
2
by: =?Utf-8?B?VG9tIEFsbGVu?= | last post by:
Hi, TIA for any help. (Thanks, Mattias Sjögren for your help yesterday! ) I am developing a C# wrapper for a 3rd party API. It processes buffers from a video stream (file) and is structured...
11
by: Daniel Bass | last post by:
Greetings! I'm trying to call this method in a c# app... SNAPIDLL_API int __stdcall SNAPI_SetCapabilitiesBuffer(HANDLE DeviceHandle, unsigned char *pData, long max_length); So far I've got...
1
by: =?Utf-8?B?bGlnaHRkb2xs?= | last post by:
hello everyone. i have made a dll of c++/cli, then i want to exchange structure between c++/cli and c. this is the structure typedef struct tagExchange {
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.