Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > ошибка при компиляции


Автор: Andrej78 24.3.2011, 15:10
Доброго времени суток.

Пытаюсь разобраться в DDE, т.к. нужно получить данные из проги, которая экспорт делает по DDE.

Нашел пример, использующий ddeml.h в MSDN.
при компиляции vs2005 выдает ошибку:

1>MSVCRTD.lib(crtexe.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
1>C:\ddesv.exe : fatal error LNK1120: 1 unresolved externals

Подскажите пожалуйста, как с этим можно бороться?
И где можно посмотреть команды winapi для работы с dde (чтобы легче было понять).

Оригинал примера тут:
http://support.microsoft.com/kb/238133/ru

Сам пример вот(только подправил char на L"" и добавил стандартный stdafx.h):
компилировать пытаюсь как win32 проект с precompile headers

Код

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <ddeml.h>


// Globals...
HSZ g_hszAppName;
HSZ g_hszTopicName;
HSZ g_hszItemName;
int g_count = 0;
DWORD g_idInst = 0;

// Declarations:
HDDEDATA EXPENTRY DdeCallback(UINT type, UINT fmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, DWORD dwData1, DWORD dwData2);

// WinMain()..
int APIENTRY /*_t*/WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
   
   // Initialize DDEML...
   if(DdeInitialize(&g_idInst, DdeCallback, APPCLASS_STANDARD, 0)) {
      MessageBox(NULL, L"DdeInitialize() failed", L"Error", MB_SETFOREGROUND);
      return -1;
   }
   
   // Create string handles...
   g_hszAppName = DdeCreateStringHandle(g_idInst, L"DdemlSvr", NULL);
   g_hszTopicName = DdeCreateStringHandle(g_idInst, L"MyTopic", NULL);
   g_hszItemName = DdeCreateStringHandle(g_idInst, L"MyItem", NULL);
   
   if( (g_hszAppName == 0) || (g_hszTopicName == 0) || (g_hszItemName == 0) ) {
      MessageBox(NULL, L"DdeCreateStringHandle() failed", L"Error", MB_SETFOREGROUND);
      return -2;
   }
   
   // Register DDE server
   if(!DdeNameService(g_idInst, g_hszAppName, NULL, DNS_REGISTER)) {
      MessageBox(NULL, L"DdeNameService() failed!", L"Error", MB_SETFOREGROUND);
      return -3;
   }
   
   // Create a timer to simulate changing data...
   SetTimer(0,0,1,0);
   
   // Message loop:
   MSG msg;

   while (GetMessage(&msg, NULL, 0, 0))  {
      // On WM_TIMER, change our counter, and update clients...
      if(msg.message == WM_TIMER) {
         g_count++;
         DdePostAdvise(g_idInst, g_hszTopicName, g_hszItemName);
      }
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }
   
   return (int) msg.wParam;
}


// Our DDE Callback function...
HDDEDATA EXPENTRY DdeCallback(UINT wType, UINT fmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, DWORD dwData1, DWORD dwData2) {

   switch (wType) {
      
   // ----------------------------------------------------------------
   case XTYP_CONNECT:
      // Client is trying to connect. Respond TRUE if we have what they want...
      if ((!DdeCmpStringHandles(hsz1, g_hszTopicName)) &&
         (!DdeCmpStringHandles(hsz2, g_hszAppName)))
         return (HDDEDATA)TRUE;   // SERVER supports Topic|Service
      else
         return FALSE;  // SERVER does not support Topic|Service
      
      // ----------------------------------------------------------------
   case XTYP_ADVSTART:
      // Client starting advisory loop.
      // Say "ok" if we have what they are asking for...   

      if((!DdeCmpStringHandles(hsz1, g_hszTopicName)) &&
         (!DdeCmpStringHandles(hsz2, g_hszItemName)))
         return (HDDEDATA)TRUE;   // SERVER supports Topic|Service
      else
         return FALSE;  // SERVER does not support Topic|Service
      // ----------------------------------------------------------------
            

   case XTYP_ADVREQ:
      
      // Client wants our data. Since this is specific to Excel, we'll
      // go ahead and assume they want XlTable-formatted data. For a
      // generic DDE server, you might want to handle various formats
      // specified by the passed in fmt parameter.

      if(!DdeCmpStringHandles(hsz1, g_hszTopicName) &&
         !DdeCmpStringHandles(hsz2, g_hszItemName)) {

         short xltableData[100];
         
         // tdtTable record...
         xltableData[0] = 0x0010; // tdtTable
         xltableData[1] = 4; // 2 short ints following
         xltableData[2] = 1; // # rows
         xltableData[3] = 1; // # cols
         
         // tdtInt record...
         xltableData[4] = 0x0006;
         xltableData[5] = 2;
         xltableData[6] = (short)g_count;

         return DdeCreateDataHandle(g_idInst, (UCHAR*)xltableData, 2*7, 0, g_hszItemName, fmt, 0);
      }    
      // ----------------------------------------------------------------
   default:
      return (HDDEDATA)NULL;
   }
}


Автор: azesmcar 24.3.2011, 16:21
Цитата(Andrej78 @  24.3.2011,  15:10 Найти цитируемый пост)
Подскажите пожалуйста, как с этим можно бороться?

Написать функцию main.

Автор: Andrej78 24.3.2011, 16:46
А где её написать? 

В самой программе есть _tWinMain()
ведь это не сама программа ссылается, а MSVCRTD.lib(crtexe.obj)

Автор: bsa 24.3.2011, 17:00
Andrej78, тогда поменяй тип проекта. У тебя сейчас проект консольный, а для него нужна main().

Автор: Andrej78 24.3.2011, 18:00
Поменял проект с консольного на Windows program, всё скомпилировалось и заработало.
(странно, сегодня уже так пробовал, но не компилировалось...)


Спасибо!

Теперь буду разбираться smile







з.ы.
Если кому понадобится потом, для проверки работы нужно включить прогу (окна не будет, её в диспетчере программ можно посмотреть), потом открыть эксель и в ячейку ввести:

=DdemlSvr|MyTopic!MyItem

после чего в ней появится увеличивающееся по таймеру число

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)