C++ 构建与Dreamweaver兼容的C DLL

C++ 构建与Dreamweaver兼容的C DLL,c++,c,dll,C++,C,Dll,我引用的文档在这里,非常简短,切中要害: 我遇到的问题是我不确定如何编译实际的DLL。adobe extension论坛上的最后一个回复已经有3个月了,我不知道该怎么回答这个问题 让我困惑的编程部分是我必须用C++来构建DLL,但是大多数教程都是基于构建目标应用程序包含的头文件来工作的。(我是DLL编程新手。)Dreamweaver只需要一个DLL,它已经知道它将调用什么。我对如何将这些信息单独放在DLL文件中感到困惑,尽管基于我阅读的教程,因为应用程序似乎还需要头文件或lib文件 在我的第一

我引用的文档在这里,非常简短,切中要害:

我遇到的问题是我不确定如何编译实际的DLL。adobe extension论坛上的最后一个回复已经有3个月了,我不知道该怎么回答这个问题

让我困惑的编程部分是我必须用C++来构建DLL,但是大多数教程都是基于构建目标应用程序包含的头文件来工作的。(我是DLL编程新手。)Dreamweaver只需要一个DLL,它已经知道它将调用什么。我对如何将这些信息单独放在DLL文件中感到困惑,尽管基于我阅读的教程,因为应用程序似乎还需要头文件或lib文件

在我的第一次尝试中,我使用VS2008并选择win32 DLL作为我的项目类型,然后在它生成的导出函数文件中添加了所需的函数。我的第一个是:

extern "C" __declspec(dllexport) bool SCS_Connect(void **connectionData, const char siteName[64])
{
 return true;
}
有人能帮忙澄清一下这是怎么回事吗

编辑: 重新阅读文档时,我注意到它说:

Dreamweaver确定哪些功能 该库通过调用 每个API的GetProcAddress() 功能。如果地址没有 存在时,Dreamweaver假定为库 不支持API。如果 地址存在,Dreamweaver使用 要删除的函数的库版本 支持该功能

尽管我仍然不确定这对于我编译DLL意味着什么

编辑2: 返回的依赖项:

LoadLibraryW("c:\program files\adobe\adobe dreamweaver cs3\Configuration\SourceControl\mercFlow.dll") returned 0x05110000.
GetProcAddress(0x05110000 [MERCFLOW.DLL], "MM_InitWrapper") called from "DREAMWEAVER.EXE" at address 0x00D73D4B and returned NULL. Error: The specified procedure could not be found (127).
GetProcAddress(0x05110000 [MERCFLOW.DLL], "SCS_GetAgentInfo") called from "DREAMWEAVER.EXE" at address 0x00D73D66 and returned NULL. Error: The specified procedure could not be found (127).
GetProcAddress(0x05110000 [MERCFLOW.DLL], "SCS_GetNumNewFeatures") called from "DREAMWEAVER.EXE" at address 0x00D73D72 and returned NULL. Error: The specified procedure could not be found (127).
GetProcAddress(0x05110000 [MERCFLOW.DLL], "SCS_GetNewFeatures") called from "DREAMWEAVER.EXE" at address 0x00D73D7E and returned NULL. Error: The specified procedure could not be found (127).
GetProcAddress(0x05110000 [MERCFLOW.DLL], "SCS_Connect") called from "DREAMWEAVER.EXE" at address 0x00D73E2B and returned NULL. Error: The specified procedure could not be found (127).
其中一些是在我的DLL中定义的(根据文档,有些是可选的),但找不到。这是否意味着没有导出我的函数

这是我的DLL源代码:

dllheader.h

#ifndef DLLHEADER_H_INCLUDED
#define DLLHEADER_H_INCLUDED
#ifdef DLL_EXPORT
# define EXPORT extern "C" __declspec (dllexport)
#else
# define EXPORT
#endif
DLL_EXPORT struct itemInfo;
DLL_EXPORT bool SCS_GetAgentInfo(char name[32],char version[32], char description[256], const char * dwAppVersion);
DLL_EXPORT bool SCS_Connect(void **connectionData, const char siteName[64]);
DLL_EXPORT bool SCS_Disconnect(void *connectionData);
DLL_EXPORT bool SCS_IsConnected(void *connectionData);
DLL_EXPORT int SCS_GetRootFolder_Length(void *connectionData);
DLL_EXPORT int SCS_GetFolderListLength(void *connectionData, const char *remotePath);
DLL_EXPORT bool SCS_GetFolderList(void *connectionData, const char *remotePath, itemInfo itemList[ ], const int numItems);
DLL_EXPORT bool SCS_Get(void *connectionData, const char *remotePathList[], const char *localPathList[], const int numItems);
DLL_EXPORT bool SCS_Put(void *connectionData, const char *localPathList[], const char *remotePathList[], const int numItems);
DLL_EXPORT bool SCS_NewFolder(void *connectionData,const char *remotePath);
DLL_EXPORT bool SCS_Delete(void *connectionData, const char *remotePathList[],const int numItems);
DLL_EXPORT bool SCS_Rename(void *connectionData, const char * oldRemotePath, const char*newRemotePath);
DLL_EXPORT bool SCS_ItemExists(void *connectionData,const char *remotePath);
#endif
main.cpp

#define DLL_EXPORT
#include "dllheader.h"
#include <iostream>
char* const gName="MercFlow";
char* const gVersion="1.0";
char* const gDescription="Native Mercurial Support for Dreamweaver.";


DLL_EXPORT struct itemInfo
{
    bool isFolder;
    int month;
    int day;
    int year;
    int hour;
    int minutes;
    int seconds;
    char type[256];
    int size;
};


// Description: This function asks the DLL to return its name and description, which appear in the Edit Sites dialog box. The name appears in the Server Access pop-up menu (for example, sourcesafe, webdav, perforce) and the description below the pop-up menu.
// name: The name argument is the name of the source control system. The name appears in the combo box for selecting a source control system on the Source Control tab in the Edit Sites dialog box. The name can be a maximum of 32 characters. 
DLL_EXPORT bool SCS_GetAgentInfo(char name[32],char version[32], char description[256], const char * dwAppVersion)
{
    name=gName;
    version=gVersion;
    description=gDescription;
    return true;
}
//Description: This function connects the user to the source control system. If the DLL does not have log-in information, the DLL must display a dialog box to prompt the user for the information and must store the data for later use.
DLL_EXPORT bool SCS_Connect(void **connectionData, const char siteName[64])
{
    return true;
}
DLL_EXPORT bool SCS_Disconnect(void *connectionData)
{
    return true;
}
DLL_EXPORT bool SCS_IsConnected(void *connectionData)
{
    return true;
}
DLL_EXPORT int SCS_GetRootFolder_Length(void *connectionData)
{
    return 0;
}
DLL_EXPORT bool SCS_GetRootFolder(void *connectionData, char remotePath[],const int folderLen)
{
    return true;
}
DLL_EXPORT int SCS_GetFolderListLength(void *connectionData, const char *remotePath)
{
    return 0;
}
DLL_EXPORT bool SCS_GetFolderList(void *connectionData, const char *remotePath, itemInfo itemList[ ], const int numItems)
{
    return true;
}
DLL_EXPORT bool SCS_Get(void *connectionData, const char *remotePathList[], const char *localPathList[], const int numItems)
{
    return true;
}
DLL_EXPORT bool SCS_Put(void *connectionData, const char *localPathList[], const char *remotePathList[], const int numItems)
{
    return true;
}
DLL_EXPORT bool SCS_NewFolder(void *connectionData,const char *remotePath)
{
    return true;
}
DLL_EXPORT bool SCS_Delete(void *connectionData, const char *remotePathList[],const int numItems)
{
    return true;
}
DLL_EXPORT bool SCS_Rename(void *connectionData, const char * oldRemotePath, const char*newRemotePath)
{
    return true;
}
DLL_EXPORT bool SCS_ItemExists(void *connectionData,const char *remotePath)
{
    return true;
}
#定义DLL#u导出
#包括“dllheader.h”
#包括
char*const gName=“MercFlow”;
char*const gVersion=“1.0”;
char*const gddescription=“Dreamweaver的本机Mercurial支持。”;
DLL\u导出结构itemInfo
{
bool-isFolder;
整月;
国际日;
国际年;
整小时;
整数分钟;
整数秒;
字符类型[256];
整数大小;
};
//说明:此函数要求DLL返回其名称和说明,显示在“编辑站点”对话框中。该名称显示在服务器访问弹出菜单中(例如,sourcesafe、webdav、perforce)以及弹出菜单下方的说明。
//name:name参数是源代码管理系统的名称。该名称出现在“编辑站点”对话框的“源代码管理”选项卡上用于选择源代码管理系统的组合框中。名称最多可包含32个字符。
DLL\u导出布尔SCS\u GetAgentInfo(字符名称[32],字符版本[32],字符描述[256],常量字符*dwAppVersion)
{
name=gName;
版本=gVersion;
描述=描述;
返回true;
}
//描述:此功能将用户连接到源代码管理系统。如果DLL没有登录信息,则DLL必须显示一个对话框以提示用户输入信息,并且必须存储数据以供以后使用。
DLL\u导出布尔SCS\u连接(无效**连接数据,常量字符站点名称[64])
{
返回true;
}
DLL\u导出bool SCS\u断开连接(无效*连接数据)
{
返回true;
}
DLL\u导出布尔SCS\u已连接(无效*连接数据)
{
返回true;
}
DLL\u导出int SCS\u GetRootFolder\u长度(无效*连接数据)
{
返回0;
}
DLL_EXPORT bool SCS_GetRootFolder(void*connectionData,char remotePath[],const int folderLen)
{
返回true;
}
DLL\u EXPORT int SCS\u GetFolderListLength(void*connectionData,const char*remotePath)
{
返回0;
}
DLL_EXPORT bool SCS_GetFolderList(void*connectionData,const char*remotePath,itemInfo itemList[],const int numItems)
{
返回true;
}
DLL_EXPORT bool SCS_Get(void*connectionData,const char*remotePathList[],const char*localPathList[],const int numItems)
{
返回true;
}
DLL_EXPORT bool SCS_Put(void*connectionData,const char*localPathList[],const char*remotePathList[],const int numItems)
{
返回true;
}
DLL\u导出布尔SCS\u新文件夹(无效*连接数据,常量字符*远程路径)
{
返回true;
}
DLL\u导出布尔SCS\u删除(无效*连接数据,常量字符*远程路径列表[],常量整数)
{
返回true;
}
DLL\u导出布尔SCS\u重命名(无效*连接数据,常量字符*旧远程路径,常量字符*新远程路径)
{
返回true;
}
DLL\u导出布尔SCS\u项存在(无效*连接数据,常量字符*远程路径)
{
返回true;
}

根据文档,在Dreamwaver接受DLL之前,您可能需要添加所有必需的函数。您可以使用的配置文件模式查看DW加载DLL时发生的情况。并验证DLL是否确实导出了所有必需的符号


编辑:在Dependency Walker的模块树或模块列表中选择DLL,然后查看右侧的导出列表(第一列标题中显示“E”),并确保所有必需的函数都存在。如果GetProcessAddress在其中一个必需的函数上失败,则需要添加该函数。

目标应用程序仅包含一个头/链接一个用于自动链接的库。通过GetProcAddress手动链接不需要任何这样的功能-您可以在随机DLL上调用GetProcAddress并查找函数。当您尝试编译时会发生什么情况,是否收到错误消息?编译成功。我很容易把东西编译好。这只是为了让Dreamweaver能够正确地看到函数而进行编译。这是一个好主意,但我相信Dreamweaver正在使用dependency Walker所称的延迟加载依赖模块。对于API DLL。直到我在Dreamweaver中转到site>new site,错误(尝试加载)才真正发生。现在看看……我希望我能再次投你一票。这是非常有用的。我刚刚编辑了我的回复,希望这是正确的做法,所以:)不,他们是