Click here to Skip to main content
15,889,339 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
I've got a manufacturer's DLL that operates a video card. Since it uses unmanaged code, I am writing a wrapper DLL in C++


I'm just trying to get it the callback to function properly, so I eliminated all code inside it.

C++ Side
.h
extern "C" _declspec(dllexport) int StartCapture(void);
int NewFrameCallback(int lParam, int nID, int nDevNum, int nMuxChan, int nBufSize, BYTE* pBuf);
class IDVP7010BDLL
{
public:
   virtual ~IDVP7010BDLL() {}   
    virtual int AdvDVP_Start(int nDevNum, int SwitchingChans, HWND Main, HWND hwndPreview) PURE;
    virtual int AdvDVP_SetNewFrameCallback(int nDevNum, int callback) PURE;
};


.cpp
int NewFrameCallback(int lParam, int nID, int nDevNum, int nMuxChan, int nBufSize, BYTE* pBuf)
{
return 1;
}
int StartCapture()
{
    int res;
    res = pDVPSDK->AdvDVP_SetNewFrameCallback(0, (int)NewFrameCallback);
            if (res !=  SUCCEEDED)
            {
                return res;
            }
            //Start Video Capture
            res = pDVPSDK->AdvDVP_Start(0,0,NULL,NULL);
            if (res !=  SUCCEEDED)
            {
                return res;
            }
}


C# side

C#
//Import
[DllImport(@".\VideoWrapper.dll")]
       public static extern int StartCapture();
//run
Res = VideoWrapper.StartCapture(); 



Now, the code runs fine if I comment out the
//res = pDVPSDK->AdvDVP_SetNewFrameCallback(0, (int)NewFrameCallback);


However, once added in, the program crashes with a memory access violation.

The program '[2880] BioPacVideo.vshost.exe: Managed (v4.0.30319)' has exited with code -1073741819 (0xc0000005).

Since I am calling a DLL from a DLL, is there something special I might be missing? Thank you advance!

Also, I culled down the import DLL class IDVP7010BDLL to make for an easier read. Hopefully that isn't confusing.
Posted
Comments
[no name] 8-Mar-11 5:46am    
Hey what i understand,
if you called dll inside one dll then both dlls must present in your working directory.
what i meant is that,
if you call test.dll in test1.dll
then
in your application
you should have
test.dll and test1.dll
that migth work

You don't show where pDVPSDK is initialized. Are you sure that pointer is valid?

And one important thing I see is the type of the callback parameter. It is supposed to be a function pointer but in your code it is an int. This will lead to problems if you are running this code on a 64bits platform since int is 32 bits and pointer 64 bits... In that case, ask your provider a 64 bits compatible dll.

...
I was curious and searched for your SDK manual. I found this: http://support.elmark.com.pl/advantech/pdf/DVP-7010Bman.pdf[^]
The callback prototype is different from yours: it contains 5 arguments instead of 6. But you probably have a newer version of the SDK (?).
Anyway this can't be the problem since the function is just supposed to assign a pointer (it would crash at a later time while calling the callback).

I don't have many more ideas, maybe a stack corruption? It can be due to a mismatch between the IDVP7010BDLL class delcaration and the real content of the dll. It may happen if you updated your card drivers without updating the SDK (or opposite). So check that the version of the dll you are using matches the version of your SDK.

You can also try to make it work first in a native application. For example, the SDK probably comes with a set of sample applications with code: compile the samples (the ones with the callback function of course) and test them to see if they crash or not. If they crash, most likely it means you have the problem I described (mismatch version between SDK and installed drivers). It they don't crash, then check carefully what are the differences between your code and theirs...

If you still can't fix it, I advise you to ask directly to the card provider (or distributor): they probably have a technical team that could help you.
 
Share this answer
 
v2
Comments
DarkKobold 8-Mar-11 11:46am    
Sorry, I left this out to make an easier read.
hDll = LoadLibrary(TEXT("D:\\WINDOWS\\system32\\DVP7010B.dll"));
if (hDll)
{
AdvDVP_CreateSDKInstence = (ptr_func1)GetProcAddress(hDll, (LPCSTR)"AdvDVP_CreateSDKInstance");
}
else return 2;

if (AdvDVP_CreateSDKInstence)
{
ErrorVal = AdvDVP_CreateSDKInstence((void **)&pDVPSDK);
if (ErrorVal != SUCCEEDED)
return ErrorVal;
}

Also, I am on a 32bit OS, as the driver for this video card only works in 32bit XP.
Olivier Levrey 8-Mar-11 12:00pm    
OK. It would be even better to check the returned pointer, but I suppose the function would not return SUCCEEDED if the pointer was wrong.
And does the other call succeed? res = pDVPSDK->AdvDVP_Start(0,0,NULL,NULL);
Or does it crash like the first one?
DarkKobold 8-Mar-11 15:12pm    
Yes, that returns succeeded as well, as long as the callback assignment is commented out. The only thing that causes the crash is assigning the callback.
Olivier Levrey 9-Mar-11 4:05am    
I updated my answer.
DarkKobold 9-Mar-11 17:22pm    
Olivier - Wow, thank you for doing so much research. Unfortunately, that manual has quite a few errors in it, as many functions don't match the calls performed in the SDK. I copied, verbatim, the function calls in their SDK example, (which is a Visual C++ app), and everything works fine except for this one last piece, the callback. (I also tried changing the function call to the one listed in the manual, to no avail.) Also, I am able to compile their example application, and the callback works fine. This is why I think it has something to do with it being wrapped inside a DLL... Do DLLs need something special to have callbacks?

Anyway, I contacted the company to let them know of these errors in the manual, as well as my question about the callback. I understand if you can't help any further, and thanks for everything you've done.

EDIT: Actually, I was thinking about it - maybe I need to send the function address from C#, as a delegate? If somehow it can't address the function inside the DLL, I can send it the same function from C# itself? I have no idea how to do that, but I'm totally lost otherwise.
Can can import LoadLibrary(), GetProcAddress() and FreeLibrary()
Then use a delegate to use the function and make a call using the delegate.

I hope this method will work for you.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900