我想用纯c写一个lib 或者 dll , 但在MFC下不能调用, 所以我估计是版本的问题 , 我现在想用vc重新写一个 , 那位大虾能指点一下,谢谢
    最好能给个例程,实现一个视频播放器的接口.
    另外在ActiveX 调用自己写的lib或者 dll , 怎样调用?
    谢谢

解决方案 »

  1.   

    lib文件是在制作DLL的时候生成的,下面是转贴的一篇文章:通常我们在调用DLL时所需的DLL文件必须位于以下三个目录之一: 
      (1)Windows的系统目录:\windows\system;
      (2)DOS中path所指出的任何目录;
      (3)程序所在的目录。
      一、动态链接库的结构
      动态链接库中定义有两种函数:导出函数(export function)和内部函数(internal function),导出函数可以被其它模块调用,内部函数只能在库内部使用。我们在用C++定制动态库文件时,需要编写的就是包含导出函数表的模块定义文件(.DEF)和实现导出函数功能的C++文件。下面以Sample.dll为例介绍DEF文件和实现文件的结构。
      1.模块定义文件(.DEF)是一个或多个用于描述DLL属性的模块语句组成的文本文件,每个DEF文件至少必须包含以下模块定义语句:
      ·第一个语句必须是LIBRARY语句,指出DLL的名字;
      ·EXPORTS语句列出被导出函数的名字;
      ·可以使用DESCRIPTION语句描述DLL的用途(此句可选);
      ·“;”对一行进行注释(可选)。
      2.实现文件  实现入口表函数的cpp文件中,包含DLL入口点处理的API函数和导出函数的代码。  二、创建Sample.dll   1.首先创建Sample.dll的工程,启动VC++5.0按以下步骤生成DLL工程:  ·在选单中选择File\New\Project;  ·在工程列表中选择Win32 Dynamic-Link Library;  ·在Project Name中输入工程名:Sample;  ·单击Location右边按钮,选择c:\sample目录;  ·单击OK完成,至此已创建了Sample.dll的工程文件。  2.创建Sample.def文件:  ·在选单中选择File\New\Text File;  ·输入以下代码后保存文件名“Sample.def”:   ;Sample.def   ;指出DLL的名字Sample,链接器将这个名字放到DLL导入库中   LIBRARY Sample   ;定义导出函数ShowMe()为例
       EXPORTS   ShowMe   ;def文件结束  3.创建Sample.cpp   .在选单中选择File\New\C++ Source File项   .输入以下代码后保存文件名“Sample.cpp”   //Sample.cpp   #include 〈windows.h〉   int ShowMe(void);   //DllEntryPoint为DLL入口点函数,负责初试化并终止DLL   BOOL WINAPI DllEntryPoint(HINSTANCE hDLL,DWORD dwReason,LPVOID Reserved)   { switch(dwReason)   { case DLL—PROCESS—ATTACH:   { break; }   case DLL-PROCESS-DETACH:   { break; } }   return TRUE; }   int ShowMe(void)   { //蜂鸣器响一下   MessageBeep((WORD)-1);   MessageBox("你好!");   return 1; }  4.编译DLL文件  从Build选单中选择Build Sample.DLL,产生Sample.DLL文件,以后就可以随时调用了。  三、在应用程序中调用DLL文件  在应用程序中要首先装入DLL后才能调用导出表中的函数,例如用MFC创建基于对话框的工程Test,并在对话框上放置“Load”按钮,你就必须添加装载代码。  1.首先在TestDlg.cpp的首部添加变量设置代码:  //设置全局变量gLibSample用于存储DLL句柄  HINSTANCE gLibSample=NULL;  //第二个变量ShowMe是指向DLL库中ShowMe()函数的指针  typedef int( SHOWME)(void);
      SHOWME ShowMe;  2.利用ClassWizard为“Load”按钮添加装载DLL的代码:  Void CTestDlg::OnLoadButton()  { //要添加的代码如下   if(gLibMyDLL!=NULL)   { MessageBox("The Sample.DLL has already been load.");   return; }   //装载Sample.dll,未加路径,将在三个默认路径中寻找   gLibSample=LoadLibrary("SAMPLE.DLL");   //返回DLL中ShowMe()函数的地址   ShowMe=(SHOWME)GetProcAddress(gLibSample,"ShowMe"); }  3.只要DLL装载成功,在应用程序中就可以直接调用ShowMe()函数.
      

  2.   

    嗯,vc下可以直接新建LIB和DLL的工程,然后将你的.c和.h文件包含进去,编译就可以了
      

  3.   

    关于VC中的DLL的编程    在我们实际用软件时,经常可看到许多动态连接库。动态连接库有其自身的优点
    如节省内存、支持多语种等功能,而且,当DLL中的函数改变后,只要不是参数的改变
    调用起的函数并不需要重新编译。这在编程时十分有用。至于其他妙处,各位在电脑
    杂志、书籍中都能看到,我这里再说就是废话了.
        这次小弟我所要讲的是如何在VC5.0中如何做自己的Win32 DLLs,各位要做自己的
    动态连接库,首先要知道DLL在VC5.0中都有哪几种分类。VC支持三种DLL,它们是:
              1.Non-MFC Dlls
            2.Regular Dlls
            3.Extension Dlls
        Note:翻译措辞不当,故遇到术语是引用原词
        Non-MFC DLL:指的是不用MFC的类库结构,直接用C语言写的DLL,其输出的函数一
    般用的是标准C接口,并能被非MFC或MFC编写的应用程序所调用。
        Regular DLL:和下述的Extension Dlls一样,是用MFC类库编写的。明显的特点是
    在源文件里有一个继承CWinApp的类。其又可细分成静态连接到MFC和动态连接到MFC上
    的。但静态连接到MFC的动态连接库只被VC的专业般和企业版所支持。
        Extension DLL:用来实现从MFC所继承下来的类的重新利用,也就是说,用这种类
    型的动态连接库,可以用来输出一个从MFC所继承下来的类。Extension DLL使用MFC的
    动态连接版本所创建的,并且它只被用MFC类库所编写的应用程序所调用。
        各位看到这里如果眼有点花或头有点晕,请别泄气,再看两遍,然后继续往下看,
    定有收获。   这一节介绍Non-MFC DLLs的编写方法。下面是一个通用的
    写法:BOOL APIENTRY DllMain(HANDLE hModule,DWORD  ul_reason_for_call,
                          LPVOID lpReserved)
    {
        switch( ul_reason_for_call ) {
        case DLL_PROCESS_ATTACH:
            .......
        case DLL_THREAD_ATTACH:
            .......
        case DLL_THREAD_DETACH:
            .......
        case DLL_PROCESS_DETACH:
            .......
        }
        return TRUE;
    }
        每一个DLL必须有一个入口点,这就象我们用C编写的应用程序一样,
    必须有一个WINMAIN函数一样。    在这个示例中,DllMain是一个缺省的入口函数,你不需要编写自己
    的DLL入口函数,并用linker的命令行的参数开关/ENTRY声明。用这个缺
    省的入口函数就能使动态连接库被调用时得到正确的初始化,当然了,你
    不要在初始化的时候填写使系统崩溃的代码了。
        参数中,hMoudle是动态库被调用时所传递来的一个指向自己的句柄
    (实际上,它是指向_DGROUP段的一个选择符)
        ul_reason_for_call是一个说明动态库被调原因的标志。当进程或线程
    装入或卸载动态连接库的时候,操作系统调用入口函数,并说明动态连接库
    被调用的原因。它所有的可能值为:
    DLL_PROCESS_ATTACH:    进程被调用
    DLL_THREAD_ATTACH:     线程被调用
    DLL_PROCESS_DETACH:    进程被停止
    DLL_THREAD_DETACH:     线程被停止
        lpReserved是一个被系统所保留的参数。
        入口函数已经写了,盛下的也不难,你可以在文件中加入你所想要输
    出的函数或变量或c++类或、或、或、?好象差部多了。look here!现在就
    要加入一个新的输出函数了:
    void _declspec(dllexport) JustSoSo()
    {
            MessageBox(NULL,"It's so easy!","Hahaha......",MB_OK);
    }
         要输出一个类也可以,如下:
    class _declspec(dllexport) Easy
    {
     //add your class definition...
    };
         各位一定注意到在输出函数或类是我用到_declspec(dllexport),
    这是VC提供的一个关键字,用它可在动态连接库中输出一个数据、
    一个函数或一个类。用这个关键字可省你不少事,你不用在.DEF文件
    中说明我要输出这个类、那个函数的 ?
        前面讲到Non-MFC DLL的编法,现在讲讲调用DLL的方法。对DLL的
    调用分为两种,一种是显式的调用,一种是隐式的调用。
        所谓显式的调用,是指在应用程序中用LoadLibrary或MFC提供的
    AfxLoadLibrary显式的将自己所做的动态连接库调近来,动态连接库
    的文件名即是上两函数的参数,再用GetProcAddress()获取想要引入
    的函数。自此,你就可以象使用如同本应用程序自定义的函数一样来
    调用此引入函数了。在应用程序退出之前,应该用FreeLibrary或
    MFC提供的AfxLoadLibrary释放动态连接库。    隐式的调用则需要把产生动态连接库时产生的.LIB文件加入到应
    用程序的工程中,想使用DLL中的函数时,只须说明以下,如下:说明
    上篇的输出函数void JustSoSo();    _declspec(dllimport) void JustSoSo();    隐式调用不需要调用LoadLibrary()和FreeLibrary().    由此看来,隐式说明调用的方法比较简单,但DLL改变后,应用程序
    须从新编译。并且,所有所调用的DLL在应用程序加载的同时被加载到内
    存中,但应用程序调用的DLL比较多时,装入的过程十分慢。隐式的调用
    则在应用程序不知道所要装入的DLL或隐式调用不成功,此时,允许用户
    指定所要加载的动态连接库,比较灵活。
        Regular DLL能够被所有支持DLL技术的语言所编写的应用程序
    所调用。在这种动态连接库中,它必须有一个从CWinApp继承下来的
    类,DllMain函数被MFC所提供,不用自己显式的写出来。下面是一个
    例子:
    // MyRegularDll.h:main header file for the MYREGULARDLL DLL
    #include "resource.h"           // main symbols
      

  4.   

    class CMyRegularDllApp : public CWinApp
    {
    public:
            CMyRegularDllApp();
    // Overrides
            // ClassWizard generated virtual function overrides
            //{{AFX_VIRTUAL(CMyRegularDllApp)
            //}}AFX_VIRTUAL
            //{{AFX_MSG(CMyRegularDllApp)
                    // NOTE - the ClassWizard will add and
                    // remove member functions here.
                    // DO NOT EDIT what you see in these blocks
                    // of generated code !
            //}}AFX_MSG
            DECLARE_MESSAGE_MAP()
    };//MyRegularDll.cpp:Defines the initialization routines for the DLL.
    //#include "stdafx.h"
    #include "MyRegularDll.h"
    //      Note!
    //
    //              If this DLL is dynamically linked against the MFC
    //              DLLs, any functions exported from this DLL which
    //              call into MFC must have the AFX_MANAGE_STATE macro
    //              added at the very beginning of the function.//
    //              For example:
    //
    //              extern "C" BOOL PASCAL EXPORT ExportedFunction()
    //              {
    //                      AFX_MANAGE_STATE(AfxGetStaticModuleState());
    //                      // normal function body here
    //              }
    //
    //              It is very important that this macro appear in each
    //              function, prior to any calls into MFC.  This means that
    //              it must appear as the first statement within the
    //              function, even before any object variable declarations
    //              as their constructors may generate calls into the MFC
    //              DLL.BEGIN_MESSAGE_MAP(CMyRegularDllApp, CWinApp)
            //{{AFX_MSG_MAP(CMyRegularDllApp)
                    // NOTE - the ClassWizard will add
                    // and remove mapping macros here.
                    // DO NOT EDIT what you see in these blocks
                    // of generated code!
            //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    ////////////////////////////////////////////////////////////
    // CMyRegularDllApp construction
    CMyRegularDllApp::CMyRegularDllApp()
    {
            // TODO: add construction code here,
            // Place all significant initialization in InitInstance
    }
         以上是AppWizard产生的含有主要代码的两个文件,各位可从中
    看出和Non-MFC Dlls的区别。但要注意上面的AppWizard的提醒啊。
        这次要讲的是最后一种动态连接库:Extension Dlls.再次说明,
    Extension Dll只被用MFC类库所编写的应用程序所调用.在这种动态
    连接库中,你可以从MFC继承你所想要的、更适于你自己用的类,并
    把它提供给你的应用程序。你也可随意的给你的应用程序提供MFC或
    MFC继承类的对象指针。
        Extension DLLs 和Regular DLLs不一样,它没有一个从CWinApp
    继承而来的类的对象,所以,你必须为自己DllMain函数添加初始化
    代码和结束代码.如下:#include "stdafx.h"
    #include <afxdllx.h>static AFX_EXTENSION_MODULE PROJNAMEDLL = { NULL, NULL };extern "C" int APIENTRY
    DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
    {
        if (dwReason == DLL_PROCESS_ATTACH)
        {
            TRACE0("PROJNAME.DLL Initializing!\n");        // Extension DLL one-time initialization
            AfxInitExtensionModule(PROJNAMEDLL,
                                     hInstance);        // Insert this DLL into the resource chain
            new CDynLinkLibrary(Dll3DLL);
        }
        else if (dwReason == DLL_PROCESS_DETACH)
        {
            TRACE0("PROJNAME.DLL Terminating!\n");
        }
        return 1;   // ok
    }
       在上面代码中AfxInitExtensionMoudle函数捕捉此动态库模块
    的run-time类及其对象,以便此后CDynLinkLibrary对象创建时使
    用.
       在初始化的时NEW一个CDynLinkLibrary对象的目的在于:它
    能是Extension DLL想应用程序输出CRuntimeClass对象或资源.
       如果此动态连接库被显式的调用,还必须在DLL_PROCESS_DETACH
    选择项的执行代码上调用AfxTermEXtensonModule,这保证了当调
    用进程与动态连接库分离是正确清理内存中的动态库模块。如果是
    隐式的被调用,则此步不是必须的了。    以上是我对于编动态连接库的一点介绍,至于实际中选用那种类型
    的动态库,则要根据实际编程所要实现的功能来决定。Non-MFC DLLS编
    起来比较简单,建议各位要编的话从它开始。其他两种实现的功能则比
    较强,编熟之后,不妨试一试。
                                                         
      

  5.   

    第1步,利用VC向导,建立一个“MFC ActiveX ControlWizard”工程,项目名可定为“TmpOcx”。一路默认下去完成向导。第2步,在CtmpOcxCtrl类的“MFC ClassWizard”里切换到“Automation”页,添加属性和方法。点击“Add Property”按钮,添加一个“MsgContext属性,类型为BSTR,点击 “Add Method”添加一个“ShowMessage”方法,没有返回.                                                                                      
    第3步:实现属性和方法。在CtmpOcxCtrl类里添加一个私有变量m_MsgContext。Private:   CString m_MsgContext; (2)属性实现方法:BSTR CTmpOcxCtrl::GetMsgContext() {    return m_MsgContext.AllocSysString();} void CTmpOcxCtrl::SetMsgContext(LPCTSTR lpszNewValue) {       if (m_MsgContext.Compare(lpszNewValue) != 0 )       {              m_MsgContext = lpszNewValue;              SetModifiedFlag();       }} (3) ShowMessage实现方法:void CTmpOcxCtrl::ShowMessage() {   AfxMessageBox(m_MsgContext);} 第4步:编辑属性编辑框。(1)在资源编辑器,编辑属性对话框(2)给输入框控件添加关联变量,也是利用MFC Classwizards来实现,
     (3)     在CtmpOcxCtrl类的DoPropExchange方法里添加如下代码,关联属性。PX_String(pPX,"MsgContext",m_MsgContext,"欢迎使用此Acitvex,呵呵"); 至此,除了事件之外,别的功能都实现了。 第5步,添加事件。在这里,我们添加一个当MsgContext属性被改变时的通知事件。实现很简单,请看如下步骤:在类CtmpOcxCtrl的MFC ClassWizards向导里的“Activex Event”页里,添加一个事件,
    (2)在CTmpOcxCtrl类的SetMsgContext方法里,触发MsgContext值变的事件。 void CTmpOcxCtrl::SetMsgContext(LPCTSTR lpszNewValue) {       if (m_MsgContext.Compare(lpszNewValue) != 0 )       {              m_MsgContext = lpszNewValue;              FireOnMsgChange();              SetModifiedFlag();       }} 最后编译运行,将自动注册此Ocx。