tags:

views:

43

answers:

1

The documentation I am referencing is here, and is fairly short and to the point: http://livedocs.adobe.com/en_US/Dreamweaver/9.0_API/help.html?content=dwr_sourcecontrol_so_01.html

The problem I am running into is that I am not sure how to compile the actual DLL. The last reply on the adobe extension forums is 3 months old, and I am not sure where to go with this question.

The programming part that confuses me is that I have to build the DLL with C++, but most tutorials work based on building a header file that the destination application includes. (I am newer to DLL programming.) Dreamweaver only needs a DLL and it already knows what it's going to call. I am confused on how I can put this information in the DLL file alone, though based on the tutorials I have read since the applications also seem to need the header file or a lib file.

For my first try I used VS2008 and selected win32 DLL for my project type, and then in the exported function file it generated I added the required functions. My first one is below:

extern "C" __declspec(dllexport) bool SCS_Connect(void **connectionData, const char siteName[64])
{
 return true;
}

Can anyone help clarify how this might work?

Edit: Rereading the documentation I notice it says:

Dreamweaver determines which features the library supports by calling GetProcAddress() for each API function. If an address does not exist, Dreamweaver assumes the library does not support the API. If the address exists, Dreamweaver uses the library's version of the function to support the functionality.

Although I still am not sure what this means in regard to my compilation of the DLL.

Edit 2: Dependency Walker Returned:

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).

A couple of these are defined in my DLL (some are optional according to docs), but aren't found. Does this mean my functions aren't being exported?

Here is my DLL source:

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;
}
+1  A: 

According to the docs, you probably need to add all the required functions before Dreamwaver will accept your DLL. You can use Dependency Walker's profile mode to see what happens when DW loads you DLL. And also to verify that your DLL really exports all the required symbols.

EDIT: Select your DLL in Dependency Walker's module tree or module list and then look at the export list to the right (it says 'E' in the first column header) and make sure that all required functions are there. If GetProcessAddress fails on one of the required functions, you need to add that function.

torhu
This is a good idea, but I believe Dreamweaver is using delay-load dependency modules as Dependency Walker calls it. for the API DLLs. The error (attempt to load) doesn't actually occur until I goto site>new site in Dreamweaver.
Josh
Ah nvm I see now. Looking at it now...I wish I could upvote you again. This is very helpful.
Josh
I just edited my reply, hope that's the right way to do things here on SO :)
torhu
No they are not appearing. The list is empty :( It seems I am messing up on the getting the functions "added" or exported.
Josh
I got it! I used a different version of the project and figured out one of my names had an extra underscore and it was a required function. Thank you so much! Dependency Walker was perfect!
Josh
Cool! The code you posted looks like it wouldn't work, though. You probably meant to prefix the functions with EXPORT instead of DLL_EXPORT. By the way, Dreamweaver won't need that header file.
torhu
Yea, I tried going at the DLL with the windows project setup rather than scratch, and that version is the one that ended up working. Thanks for the catch on the EXPORT thing though. I'll try that, it would be nice to use that version since its more to the point. You honestly made my day. You Rock.
Josh