Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 |

 

  Вопрос: fastcall,stdcall&cdecl - что есть что? Добавлено: 31.03.05 02:19  

Автор вопроса:  Neco | Web-сайт: neco.pisem.net | ICQ: 247906854 
Вопрос в теме плюс непонятный прикол:
Был проект (не мой), я взял из него четыре файла - два заголовочных и два .c. Подключил их к моему проекту (тыкнул правой кнопкой на браузере Workspace и сделал "добавить файлы"), после этого начал юзать и добился 0 на 0 (ошибок и предупреждений) при компиляции.
Теперь непонятность: при нажатии f7 вылезла unresolved external symvol для тех функций, что я использовал. Ощущение такое что файлы .c хоть и видны в проекте, но оттуда не читается инфа (тыкание на "найти определение" для функции выдаёт диалог для поиска файлов).
Кстати вот код ошибки
main.obj : error LNK2001: unresolved external symbol "void __cdecl encode_frame(long *,unsigned long)" (?encode_frame@@YAXPAJK@Z)
Кроме того, когда я создаю свой собственный *.cpp файл и в наглую всё копирую туда, то в одной паре (*.h+new.cpp) всё проканывает, а в другой что-то кричит про разницу между Си и Си++ (что именно уже не помню, т.к. много что пробовал и тот проект уже удалил).
Вообще есть какая-нибудь разница в расширениях *.c & *.cpp? В свойствах файла эти два языка стоят через дробь - типа одно и то же, а так ли это?
И ещё. Когда я создал свой .cpp и удалил из проекта .с, то обнаружил ещё одну пакость: функции из файла .h всё ещё ссылались на тела функций в файле .с, хотя в проекте его уже не было, а вместо него был одноимённый .cpp. И чтоб показать мне эти тела, сишник открывал этот файл (.с) с диска и упрямо настаивал, что этот прототип ссылается именно на этот файл, а не на тот, что у меня в проекте. 8(
Объясните мне кто-нибудь, пожалуйста, что за хрень происходит! Ведь в том проекте, откуда я эти файлы взял всё работало на пять. Но правда там все файлы были .с, а у меня в проекте все .срр.
В чём разница и как выйти из положения?

Ответить

  Ответы Всего ответов: 13  

Номер ответа: 1
Автор ответа:
 cresta



Вопросов: 117
Ответов: 1538
 Профиль | | #1 Добавлено: 31.03.05 09:49
Такие обёртки не пробовал использовать:
#ifdef __cplusplus
  extern "C" {
#endif
....
....
#ifdef __cplusplus
  }
#endif

А вообще unresolved external symbol возникает обычно когда не найдена ф-ция в либе.

Ответить

Номер ответа: 2
Автор ответа:
  j3d1



ICQ: 8370005 

Вопросов: 34
Ответов: 466
 Профиль | | #2 Добавлено: 31.03.05 20:23

А вообще unresolved external symbol возникает обычно когда не найдена ф-ция в либе.
[/QOUTE]
либо не обьявлен *.lib

Ответить

Номер ответа: 3
Автор ответа:
 Neco



ICQ: 247906854 

Вопросов: 133
Ответов: 882
 Web-сайт: neco.pisem.net
 Профиль | | #3
Добавлено: 31.03.05 23:43
Имхо, либы ни при чём, т.к. функции мои - и они у емня же в проекте находятся...
Счас закину файл на сайт...

Ответить

Номер ответа: 4
Автор ответа:
 Neco



ICQ: 247906854 

Вопросов: 133
Ответов: 882
 Web-сайт: neco.pisem.net
 Профиль | | #4
Добавлено: 31.03.05 23:49
это скрин:
http://neco.pisem.net/cpp_problem.png
а это напильники:
http://neco.pisem.net/c_cpp.zip

Ответить

Номер ответа: 5
Автор ответа:
 cresta



Вопросов: 117
Ответов: 1538
 Профиль | | #5 Добавлено: 01.04.05 00:11
Ну так правильно, чего бы ему не ругаться на unresolved symbol, если у тебя декларация есть, а тело самой функции отсутствует.


#include <stdio.h>
#include "decl.h"
#include "code.c"

void main(){
    printf("number=%d\n",func(10));
    get
    }


Вот так не ругается, компилит, выдает ехе, правда при запуске вылетает, пока не понял почему. А "тыкание" на поиск (find definition) исправно выкидывает в файл "code.c"

Ответить

Номер ответа: 6
Автор ответа:
 cresta



Вопросов: 117
Ответов: 1538
 Профиль | | #6 Добавлено: 01.04.05 00:26
 Вот полность рабочий примерчик, исправно умножает на 20 и выводит ответ.

//======================== Options ==================
#pragma comment(linker, "/entry:main";)
#pragma comment(linker, "/subsystem:windows";)
#pragma comment(linker, "/nodefaultlib:LIBCMT /NODEFAULTLIB:OLDNAMES";)

#pragma comment(lib, "kernel32.lib";)
#pragma comment(lib, "user32.lib";)
//======================== Includes ==================
#include <windows.h>
#include <stdlib.h>

#include "decl.h"
#include "code.c"

#ifdef __cplusplus
  extern "C" {
#endif
//===============================================
void main(void){
char buffer[64];
int value=1;
int newvalue=0;

wsprintf(buffer, "value = %lu\n newvalue = %lu", value, func(10));
MessageBox(NULL, buffer,"hello from cresta",0);
}
//===============================================
#ifdef __cplusplus
  }
#endif

Ответить

Номер ответа: 7
Автор ответа:
 cresta



Вопросов: 117
Ответов: 1538
 Профиль | | #7 Добавлено: 01.04.05 00:28
В смысле умножает на 2, выдает двадцать :)

Ответить

Номер ответа: 8
Автор ответа:
 Neco



ICQ: 247906854 

Вопросов: 133
Ответов: 882
 Web-сайт: neco.pisem.net
 Профиль | | #8
Добавлено: 02.04.05 04:14
В принципе, это эквивалентно тому, чтобы просто расположить свой main в файле .c, а не .cpp. Это что же выходит, сто Си и Сплюшка несовместимы? Имхо, такого не может быть.

Ответить

Номер ответа: 9
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #9
Добавлено: 02.04.05 09:07
Это что же выходит, сто Си и Сплюшка несовместимы?
Это вообще разные языки, у них просто синтаксис похожий. Тебя же не удивляет, что в JavaScript нет функции void main()?

Ответить

Номер ответа: 10
Автор ответа:
 cresta



Вопросов: 117
Ответов: 1538
 Профиль | | #10 Добавлено: 02.04.05 09:08
Несовместимость тут ни при чём.
Ты пытаешься использовать функцию, которой нет в твоем проекте. Декларация есть (в файле "decl.h";), а сам файл, в котором содержится функция ("code.c";) ты не включил в проект.

Если смущает, что #include "code.c" указано в main.cpp, можешь перенести эту строку в decl.h. Главное, чтобы эта строка была.

Си и Сплюшка несовместимы?
Ты же видишь, что программа работает. Какая тут может быть несовместимость?

Ответить

Номер ответа: 11
Автор ответа:
 Neco



ICQ: 247906854 

Вопросов: 133
Ответов: 882
 Web-сайт: neco.pisem.net
 Профиль | | #11
Добавлено: 02.04.05 14:23
>Тебя же не удивляет, что в JavaScript нет функции void main()?
Мне проще - я не знаю джавы. 8)

>Ты пытаешься использовать функцию, которой нет в твоем проекте.
Функция есть в проекте - файл code.c виден в дереве, а это значит, что он учитывается компилятором. Вот если я при открытом проекте открою из проводника какой-нибудь сырец, то он отобразится у меня в моём открытом проекте. Но при этом он в него НЕ включится (он не будет ни компилироваться [если требует инклудов], ни ссылаться на мои функции) и НЕ будет виден в дереве проекта. А вот если я тыкну на него правой кнопкой и выберу Add to project ->MyPro, то он сразу очутится у меня в дереве и дальнейшая его успешность зависит от правильности написания.
Из этого я делаю вывод, что необязательно подключая к проекту файл инклудить его в главном. Тем более, что если переименовать файл code.c из моего примера на code.cpp (или main.cpp в main.c), то всё заработает на "ура". А всё дело я думаю в том, что "прототип функции" (в отличие от переменной) автоматом объявляется extern'ом (переменная же static'ом), а т.к. при этом необходимо, что в моём проекте было лишь одно одномённое с этим прототипом тело функции, то видать дело происходит так: процедура (к примеру, main) видит только прототип (который в инклуднутом *.h) и вызывает по нему функцию. Прототип "смотрит" из какого типа исходника (сишного или сплюшного) к нему обратились (точнее в каком типе расположен *.h) и ищёт тело в таком же. Если не находит, то unresolved external symvol, что видимо надо читать как "чувак, ты объявил external'ом эту хрень, а хреновины я не вижу".
Эту теорию я тока что опробовал включив в свой проект два почти одинаковых файла code.cpp и code.c. В одном моя func умножала аргумент на 2 перед возвратом, а в другом на 3.
Так вот когда я заключал инклуд в такие вот тиСки:
extern "C" {
#include "decl.h"
}
то она main печатала number=30, а когда я комментировал вот так:
//extern "C" {
#include "decl.h"
//}
то начинала печатать number=20.
В обоих случаях файлы .c или .cpp я не инклудил, т.к. раньше я пытался это делать, но потом обнаружил, что после этого шаг влево или вправо (при операциях с файлами - добавлении нового к примеру) вызывает redefenition, т.е. это надо дополнительно инструкции для препроцессора вводить, типа:
#ifndef MYDEF {
#define MYDEF
// и далее все объявления...
#endif
Короче, имхо, гимор это и для нормального исходника, видимо, надо транслировать нужный код, а для этого, млин, надо уяснить разницу между Си и СиПиПи.
---------------------------------
Запомните, дети! "Вилька" и "тарелька" пишутся без мягкого знака, а "сол" и "фасол" с мягким знаком. Что очень трудно понять.
---------------------------------
Вот такой же и этот Си. 8)

Ответить

Номер ответа: 12
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #12
Добавлено: 02.04.05 14:44
Мне проще - я не знаю джавы.
И даже того, что Java и JavaScript - разные языки? :)
Запомните, дети! "Вилька" и "тарелька" пишутся без мягкого знака, а "сол" и "фасол" с мягким знаком. Что очень трудно понять.
Для того, чтобы таких проблем не возникало, нужно для ознакомления с языком С/С++ прочитать какую-нибудь одну хорошую книжку по нему. Метод обучения "тыком", который очень неплохо работает в случае с VB, здесь не проходит. А то и получается, что аццы MFC не знают, что адрес массива обозначается его именем. После прочтения какой-нибудь достаточно хорошей книжки, Си(++) кажется крайне логичным и стройным языком. Это не просто слова, я через это проходил.

Ответить

Номер ответа: 13
Автор ответа:
 cresta



Вопросов: 117
Ответов: 1538
 Профиль | | #13 Добавлено: 02.04.05 14:48
Функция есть в проекте - файл code.c виден в дереве, а это значит, что он учитывается компилятором

То, что он есть в дереве - ничего не значит. Учитывает его линкер или нет - видно по unresolved external symbol. А то что действительно учитывается в твоём проекте, можешь посмотреть в файле .dsp

Из этого я делаю вывод, что необязательно подключая к проекту файл инклудить его в главном
Вывод ни на чем не основанный. Необязательно в главном, но инклюдить - обязательно :)

В асме тоже так: файл в дереве отображается, но только отображается, не более. Нужно оговаривать include "myInclude.inc". Дерево - это всего лишь кусочек проводника, не более того.


Впрочем ладно, делай как хочешь...
Не мне ж на грабли наступать :)

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам