• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 294
  • Last Modified:

Create Dll that use another dll...

Hi !
I'm not really comfortable with VC++, but I've to use it...
I received an API from a company, it's a VC++ dll.  But I want to use it from VB.
Because of name mangling, I cannot use it from VB

The API they supplied with a sample application (VC++ exe) with many dialogs.  I don't need such a think, I need to call function from VB, the same kind of app without dialogs...
Also, please explain to me what is callback function, I might have to take care of this too...
OUF !!!
Here is code sample of main app.
Please contact floydus27@hotmail.com
if you have questions...

I NEED TO USE THE SAME FUNCTIONS FROM VB, I THOUGHT ABOUT CREATING A DLL THAT CALLS THESES FUNCTIONS...  BUT HAVE NO CLUE HOW DO IT...
I tried but got memory cannot be read all the time.
Could you supply me a sample of a created dll that loads an existing dll.


// BasicSDKTestAppDlg.cpp : implementation file
//

#include "stdafx.h"
#include "BasicSDKTestApp.h"
#include "BasicSDKTestAppDlg.h"
#include "VideoExportDialog.h"
#include "PantilCtrlDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
CBasicSDKTestAppDlg * g_pAppDlg = NULL;

class CAboutDlg : public CDialog
{
public:
      CAboutDlg();

// Dialog Data
      //{{AFX_DATA(CAboutDlg)
      enum { IDD = IDD_ABOUTBOX };
      //}}AFX_DATA

      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CAboutDlg)
      protected:
      virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
      //}}AFX_VIRTUAL

// Implementation
protected:
      //{{AFX_MSG(CAboutDlg)
      //}}AFX_MSG
      DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
      //{{AFX_DATA_INIT(CAboutDlg)
      //}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
      CDialog::DoDataExchange(pDX);
      //{{AFX_DATA_MAP(CAboutDlg)
      //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
      //{{AFX_MSG_MAP(CAboutDlg)
            // No message handlers
      //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBasicSDKTestAppDlg dialog

CBasicSDKTestAppDlg::CBasicSDKTestAppDlg(CWnd* pParent /*=NULL*/)
      : CDialog(CBasicSDKTestAppDlg::IDD, pParent)
{
      //{{AFX_DATA_INIT(CBasicSDKTestAppDlg)
            // NOTE: the ClassWizard will add member initialization here
      //}}AFX_DATA_INIT
      // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
      m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CBasicSDKTestAppDlg::DoDataExchange(CDataExchange* pDX)
{
      CDialog::DoDataExchange(pDX);
      //{{AFX_DATA_MAP(CBasicSDKTestAppDlg)
            // NOTE: the ClassWizard will add DDX and DDV calls here
      //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CBasicSDKTestAppDlg, CDialog)
      //{{AFX_MSG_MAP(CBasicSDKTestAppDlg)
      ON_WM_SYSCOMMAND()
      ON_WM_PAINT()
      ON_WM_QUERYDRAGICON()
      ON_BN_CLICKED(IDC_BTN_CONNECT, OnBtnConnect)
      ON_BN_CLICKED(IDC_BTN_DISCONNECT, OnBtnDisconnect)
      ON_BN_CLICKED(IDC_BTN_LIVE_STRM, OnBtnLiveStrm)
      ON_BN_CLICKED(IDC_BTN_PTZ_CTRL, OnBtnPtzCtrl)
      ON_BN_CLICKED(IDC_BTN_SEARCH, OnBtnSearch)
      ON_BN_CLICKED(IDC_BTN_CAMER_INFO, OnBtnCamerInfo)
      ON_BN_CLICKED(IDC_BTN_LIVE_STRM2, OnBtnLiveStrm2)
      ON_BN_CLICKED(IDC_BTN_SEARCH_STOP, OnBtnSearchStop)
      ON_BN_CLICKED(IDC_BTN_INST_REC_BEGIN, OnBtnInstRecBegin)
      ON_BN_CLICKED(IDC_BTN_INST_REC_END, OnBtnInstRecEnd)
      ON_BN_CLICKED(IDC_BTN_EXPORT, OnBtnExport)
      ON_BN_CLICKED(IDC_BTN_EVENT_LIST, OnBtnEventList)
      ON_BN_CLICKED(IDC_LOGINB, OnLoginb)
      //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBasicSDKTestAppDlg message handlers

BOOL CBasicSDKTestAppDlg::OnInitDialog()
{
      CDialog::OnInitDialog();

      // Add "About..." menu item to system menu.

      // IDM_ABOUTBOX must be in the system command range.
      ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
      ASSERT(IDM_ABOUTBOX < 0xF000);

      CMenu* pSysMenu = GetSystemMenu(FALSE);
      if (pSysMenu != NULL)
      {
            CString strAboutMenu;
            strAboutMenu.LoadString(IDS_ABOUTBOX);
            if (!strAboutMenu.IsEmpty())
            {
                  pSysMenu->AppendMenu(MF_SEPARATOR);
                  pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
            }
      }
      
      g_pAppDlg = this;
      
      // Set the icon for this dialog.  The framework does this automatically
      //  when the application's main window is not a dialog
      SetIcon(m_hIcon, TRUE);                  // Set big icon
      SetIcon(m_hIcon, FALSE);            // Set small icon
      
      // TODO: Add extra initialization here
      SetDlgItemText( IDC_STATIC_V_TIMESTAMP,"none" );
      SetDlgItemText(      IDC_STATIC_A_SAMPLEBIT,"none" );

      
      //Initialization to Dialog Value
      
      return TRUE;  // return TRUE  unless you set the focus to a control
}

void CBasicSDKTestAppDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
      if ((nID & 0xFFF0) == IDM_ABOUTBOX)
      {
            CAboutDlg dlgAbout;
            dlgAbout.DoModal();
      }
      else
      {
            CDialog::OnSysCommand(nID, lParam);
      }
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CBasicSDKTestAppDlg::OnPaint()
{
      if (IsIconic())
      {
            CPaintDC dc(this); // device context for painting

            SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

            // Center icon in client rectangle
            int cxIcon = GetSystemMetrics(SM_CXICON);
            int cyIcon = GetSystemMetrics(SM_CYICON);
            CRect rect;
            GetClientRect(&rect);
            int x = (rect.Width() - cxIcon + 1) / 2;
            int y = (rect.Height() - cyIcon + 1) / 2;

            // Draw the icon
            dc.DrawIcon(x, y, m_hIcon);
      }
      else
      {
            CDialog::OnPaint();
      }
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CBasicSDKTestAppDlg::OnQueryDragIcon()
{
      return (HCURSOR) m_hIcon;
}

//Callback functions.
VOID CBasicSDKTestAppDlg::OnConnectCallback(HSERVER hServer,LPST_CONNECT_INFO lpstConnectInfo)
{
      //lpstConnectInfo
      //AfxMessageBox("OnConnectCallback!");
      if( lpstConnectInfo->nConnectResult == _DXSDK_NET_CONNECTED )      //Connected
      {
            g_pAppDlg->SetDlgItemText(IDC_STATIC_CON_V,"Connected");
            g_pAppDlg->SetDlgItemText(IDC_STATIC_IP_V,lpstConnectInfo->szServerAddr);
            g_pAppDlg->SetDlgItemInt(IDC_STATIC_PORT_V,lpstConnectInfo->usServerPort);
            
            if( lpstConnectInfo->nLoginResult == _DXSDK_NET_LOGIN_SUCCESS )      //Connect Success
            {
                  g_pAppDlg->SetDlgItemText(IDC_STATIC_USER_V, lpstConnectInfo->szUserID);
            }
            else if( lpstConnectInfo->nLoginResult == _DXSDK_NET_LOGIN_FAILED )      //Connect fail
            {
                  g_pAppDlg->SetDlgItemText(IDC_STATIC_USER_V,"Login fail");
            }
      }
      else if( lpstConnectInfo->nConnectResult == _DXSDK_NET_CONNECT_FAIL ) //Connect Fail.
      {
            g_pAppDlg->SetDlgItemText(IDC_STATIC_CON_V,"Connect fail");
            g_pAppDlg->SetDlgItemText(IDC_STATIC_IP_V,lpstConnectInfo->szServerAddr);
            g_pAppDlg->SetDlgItemInt(IDC_STATIC_PORT_V,lpstConnectInfo->usServerPort);

      }
      else if( lpstConnectInfo->nConnectResult == _DXSDK_NET_OVER_CONNECTION ) //Over user
      {
            g_pAppDlg->SetDlgItemText(IDC_STATIC_CON_V,"Over user");
            g_pAppDlg->SetDlgItemText(IDC_STATIC_IP_V,"");
            g_pAppDlg->SetDlgItemInt(IDC_STATIC_PORT_V,0);
      }
}

VOID CBasicSDKTestAppDlg::OnConnectResetCallback(HSERVER hServer)
{
      g_pAppDlg->SetDlgItemText(IDC_STATIC_CON_V,"Reset by peer");
}

VOID CBasicSDKTestAppDlg::OnLiveVideoStreamIn( HSERVER hServer, LPST_LIVE_VID_ITEM lpstVidStream )
{
      CString strRec;
      //Video
      if( lpstVidStream->stFrameItem.sRecMode & (_SCRECTYPE_SENSOR) )      //Sensor.
            strRec = "Alarm";
      else if( lpstVidStream->stFrameItem.sRecMode & (_SCRECTYPE_MOTION) )
            strRec = "Motion";
      else if( lpstVidStream->stFrameItem.sRecMode & (_SCRECTYPE_CONTINUS) )
            strRec = "Continus";
      else if( lpstVidStream->stFrameItem.sRecMode & (_SCRECTYPE_PREALARM) )
            strRec = "Prealarm";
      
      g_pAppDlg->SetDlgItemText(IDC_STATIC_V_FORMAT,strRec );
      CTime TimeStamp(lpstVidStream->stFrameItem.stVidTimeStamp);// Video Time Stamp
      
      CString strTmp;
      strTmp.Format("%s-%d",TimeStamp.Format("%Y/%m/%d-%H:%M:%S"),lpstVidStream->stFrameItem.stVidTimeStamp.wMilliseconds);
      g_pAppDlg->SetDlgItemText(IDC_STATIC_V_TIMESTAMP,strTmp);
      strTmp.Format("%d",lpstVidStream->nCh+1);
      g_pAppDlg->SetDlgItemText( IDC_STATIC_V_CH,strTmp );

      strTmp.Format("%d x %d",lpstVidStream->stFrameItem.uiWidth,lpstVidStream->stFrameItem.uiHeight);
      g_pAppDlg->SetDlgItemText( IDC_STATIC_V_RESOLUTION,strTmp );
      
      g_pAppDlg->SetDlgItemInt( IDC_STATIC_V_SIZE,lpstVidStream->stFrameItem.uiVidBufSize );

      //Audio
      //IDC_STATIC_A_TIMESTAMP,IDC_STATIC_A_CH,IDC_STATIC_A_FORMAT,IDC_STATIC_A_SAMPLEBIT,IDC_STATIC_A_SIZE
      /*
      lpstVidStream->stFrameItem.stAudTimeStamp;      
      lpstVidStream->stFrameItem.lpAudBuffer;      
      lpstVidStream->stFrameItem.uiAudBufSize;      
      lpstVidStream->stFrameItem.nformation.
      lpstVidStream->stFrameItem.lLength;            
      lpstVidStream->stFrameItem.lFormat;            
      lpstVidStream->stFrameItem.lSamplePerSecond;
      lpstVidStream->stFrameItem.lSamplePerBit;
      lpstVidStream->stFrameItem.lChannels;
      */

}

VOID CBasicSDKTestAppDlg::OnLiveVideoStreamAborted(HSERVER hServer,INT nErrCode)
{
      AfxMessageBox("Video Stream Aborted.\n");
}

// Search Result Callback.
VOID CBasicSDKTestAppDlg::OnSearchCallback(HSERVER hServer, LPSEARCH_ITEM lpSearchItem)
{
      if( !lpSearchItem )      //End of search
      {
            TRACE("End of Search.\n");
            AfxMessageBox("End of search!");
            return;
      }
      else
      {
            LPSEARCH_ITEM lpstVidStream = lpSearchItem;
            CTime TimeStamp(lpstVidStream->stFrameItem.stVidTimeStamp);// Video Time Stamp
            
            CString strTmp;
            strTmp.Format("%s-%d",TimeStamp.Format("%Y/%m/%d-%H:%M:%S"),lpstVidStream->stFrameItem.stVidTimeStamp.wMilliseconds);
            g_pAppDlg->SetDlgItemText(IDC_STATIC_V_TIMESTAMP,strTmp);
            strTmp.Format("%d",lpstVidStream->nChannel+1);
            g_pAppDlg->SetDlgItemText( IDC_STATIC_V_CH,strTmp );

            strTmp.Format("%d x %d",lpstVidStream->stFrameItem.uiWidth,lpstVidStream->stFrameItem.uiHeight);
            g_pAppDlg->SetDlgItemText( IDC_STATIC_V_RESOLUTION,strTmp );
            
            g_pAppDlg->SetDlgItemInt( IDC_STATIC_V_SIZE,lpstVidStream->stFrameItem.uiVidBufSize );
            Sleep( 30 );
      }
}

//////////////////////////////////////////////////////////////////////////////////////////////////
void CBasicSDKTestAppDlg::OnBtnConnect()
{
      // TODO: Add your control notification handler code here
      ST_SERVER_BASE_INFO stServerInfo;
      
      strcpy( stServerInfo.szServerAddr, "192.168.0.1");
      stServerInfo.usServerPort = 9002;

      strcpy( stServerInfo.szUserID,"usager");
      strcpy(stServerInfo.szUserPasswd,"pelco2");

      stServerInfo.lpfnConectCallback = CBasicSDKTestAppDlg::OnConnectCallback;
      stServerInfo.lpfnDisconnectCallback = CBasicSDKTestAppDlg::OnConnectResetCallback;

      SetDlgItemText(IDC_STATIC_CON_V,"Try connect");
      
      m_hServer = ::DxConnect(&stServerInfo);
      
      if( !m_hServer )
            SetDlgItemText(IDC_STATIC_CON_V,"Network error.");
}

void CBasicSDKTestAppDlg::OnBtnDisconnect()
{
      // TODO: Add your control notification handler code here
      ::DxClose(m_hServer);
      SetDlgItemText(IDC_STATIC_CON_V,"Disconnect");
}

void CBasicSDKTestAppDlg::OnBtnLiveStrm()
{
      // TODO: Add your control notification handler code here
      LIVE_VID_CONF LiveConf;
      memset(LiveConf.btChEnable,0x00,sizeof(BYTE)*MAX_SUPPORT_CH);

      for( int nCnt=0;nCnt<16;nCnt++)
      {
            CButton *pBtn = (CButton *)GetDlgItem(IDC_CHECK1+nCnt);
            LiveConf.btChEnable[nCnt] = pBtn->GetCheck() ? 1:0;
      }
      
      LiveConf.lpfnAbortedCallback = CBasicSDKTestAppDlg::OnLiveVideoStreamAborted;
      LiveConf.lpfnVidStreamCallback = CBasicSDKTestAppDlg::OnLiveVideoStreamIn;
      LiveConf.uiMinimumStreamIntervalMS = 0;

      LiveConf.VidForat = FORMAT_RGB24;      //or FORMAT_YUV16
      
      ::DxBeginLiveStream( m_hServer, &LiveConf );
}

void CBasicSDKTestAppDlg::OnBtnLiveStrm2()
{
      // TODO: Add your control notification handler code here
      ::DxStopLiveStream( m_hServer );
}

void CBasicSDKTestAppDlg::OnBtnPtzCtrl()
{
      // TODO: Add your control notification handler code here
      CPantilCtrlDlg * pPanTiltDlg;
      pPanTiltDlg = new CPantilCtrlDlg(this,m_hServer);
      
      pPanTiltDlg->DoModal();

      delete pPanTiltDlg;
      
}

void CBasicSDKTestAppDlg::OnBtnSearch()
{
      // TODO: Add your control notification handler code here
      DXSEARCH_INFO SearchInfo;

      memset(SearchInfo.btChannel,0x00,sizeof(BYTE)*32);
      
      for( int nCnt=0;nCnt<16;nCnt++)
      {
            CButton *pBtn = (CButton *)GetDlgItem(IDC_CHECK1+nCnt);
            SearchInfo.btChannel[nCnt] = pBtn->GetCheck() ? 1:0;
      }
      //SearchInfo.lEventType; ignored. - current not use.
      SearchInfo.lpfnSearchResultCallback = CBasicSDKTestAppDlg::OnSearchCallback;
      
      SearchInfo.stStartTime.wYear = 2004;
      SearchInfo.stStartTime.wMonth = 6;
      SearchInfo.stStartTime.wDay = 15;
      SearchInfo.stStartTime.wHour = 10; //AM
      SearchInfo.stStartTime.wMinute = 0;
      SearchInfo.stStartTime.wSecond = 0;
      SearchInfo.stStartTime.wMilliseconds = 0;
      SearchInfo.stStartTime.wDayOfWeek = 3;      //Monday. start is sunday = 0;
      
      //set of video Output format.
      SearchInfo.VidForat = FORMAT_RGB24;
            
      ::DxSearchStart( m_hServer, &SearchInfo );
}

void CBasicSDKTestAppDlg::OnBtnSearchStop()
{
      // TODO: Add your control notification handler code here
      ::DxSearchStop( m_hServer );
}

void CBasicSDKTestAppDlg::OnBtnCamerInfo()
{
      // TODO: Add your control notification handler code here
      
}

void CBasicSDKTestAppDlg::OnBtnInstRecBegin()
{
      // TODO: Add your control notification handler code here
      for( int nCnt=0;nCnt<16;nCnt++)
      {
            CButton *pBtn = (CButton *)GetDlgItem(IDC_CHECK1+nCnt);
            if( pBtn->GetCheck() ) ::DxInstantRecordBegin( m_hServer, nCnt );
      }
}

void CBasicSDKTestAppDlg::OnBtnInstRecEnd()
{
      // TODO: Add your control notification handler code here
      for( int nCnt=0;nCnt<16;nCnt++)
      {
            CButton *pBtn = (CButton *)GetDlgItem(IDC_CHECK1+nCnt);
            if( !pBtn->GetCheck() ) ::DxInstantRecordEnd( m_hServer, nCnt );
      }      
}

void CBasicSDKTestAppDlg::OnBtnExport()
{
      // TODO: Add your control notification handler code here
      m_ExportDlg.SetHServer(m_hServer);
      m_ExportDlg.DoModal();
}

void CBasicSDKTestAppDlg::OnBtnEventList()
{
      // TODO: Add your control notification handler code here
      m_EventListDlg.SetHServer(m_hServer);
      m_EventListDlg.DoModal();
}

void CBasicSDKTestAppDlg::OnLoginb()
{
      // TODO: Add your control notification handler code here
      
}

0
floydus
Asked:
floydus
2 Solutions
 
SteHCommented:
You can create a .def file which exports the functions by number instead of the name. That way you should be able to call them from VB as from VC++.

Callback functions are used by several common controls. Whenever a special action occurs within the commond dialog this function is called and allows to handle it in a different way. Normally they can be either supplied or set to NULL when no non default handling is wanted. See
http://support.microsoft.com/default.aspx?scid=kb;en-us;179497
for SHBrowseForFolder usage and
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/callbackfunctions/browsecallbackproc.asp
how to use the callback function.
0
 
BeyondWuCommented:
Have you ever used windows APIs directly in VB? if so, you can use the VC++ dll also, you only need to ensure the VC++ dll only exports simple APIs but not a C++ Class.

>>please explain to me what is callback function, I might have to take care of this ...
the callback function is just a normal function without any special feature, the only difference is the callback function will be called by another APIs or module, you can't call it directly.
0
 
floydusAuthor Commented:
Well, that does'nt work, I can't create a DEF files since I don't have the c++ source file of the DLL.
All the functions name are name decorated (Or name mangling) from VC++ when the Dll was compiled.  The code I putted up there was using these function with success, from VC++.

I need to make the same application from VB...
I found that a work around would be to create a new DLL that I will be able to use from VB.
I'm actually working on it.
Thanks folks.

Dave
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now