Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ C# DLL Unmanaged
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
 
//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 7-Mar-11 12:34pm
Comments
santoshmaruti at 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
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

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.
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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.
  Permalink  
v2
Comments
DarkKobold at 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 at 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 at 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 at 9-Mar-11 4:05am
   
I updated my answer.
DarkKobold at 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.
Olivier Levrey at 10-Mar-11 4:08am
   
Usually C++/CLI is more suitable for importing native code, expecially classes. But you can have a look to this link for example: http://www.codeproject.com/KB/mcpp/usingcppdll.aspx
Be carefull to use CallingConvention.ThisCall to import non-static class methods.
mbue at 10-Mar-11 17:54pm
   
I think also its a problem with the calling conventions. Most callback functions or exported function use the PASCAL (__stdcall) calling conventions.
Regards.
DarkKobold at 14-Mar-11 18:28pm
   
I had set the DLL wrapper to STDCALL. It turns out that I needed to make sure it was _CDECL calling convention. Thanks for all the help, Olivier!
Olivier Levrey at 15-Mar-11 5:13am
   
Ok good then. Say thanks to mbue as well ;)

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



Advertise | Privacy | Mobile
Web04 | 2.8.140709.1 | Last Updated 9 Mar 2011
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid