inline
. Пример: -
main.cpp
#include "gum.h"
#include "foo.h"
int main()
{
gum();
foo f;
f.bar();
return 0;
}
foo.h (1)
#pragma once
struct foo {
void bar() const;
};
gum.h (1)
#pragma once
extern void gum();
foo.cpp (1)
#include "foo.h"
#include <iostream>
inline /* <- wrong! */ void foo::bar() const {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
gum.cpp (1)
#include "gum.h"
#include <iostream>
inline /* <- wrong! */ void gum()
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
Если вы укажете, что gum
(аналогично, foo::bar
) является inline
в своем определении, то компилятор будет встроен gum
(если он выберет) , посредством: -
gum
, и, следовательно, gum
, и вместо этого gum
встроенными копиями скомпилированного тела из gum
. В результате, если вы определяете gum
inline в исходном файле gum.cpp
, он компилируется в объектный файл gum.o
, в котором все вызовы gum
являются встроенными, и символ не определен под которым линкер может ссылаться на gum
. Когда вы связываете gum.o
в программу вместе с другим объектным файлом, например, main.o
, которые делают ссылки на внешний символ gum
, компоновщик не может разрешить эти ссылки. Таким образом, связь не работает:
Компиляция:
g++ -c main.cpp foo.cpp gum.cpp
Ссылка:
$ g++ -o prog main.o foo.o gum.o
main.o: In function `main':
main.cpp:(.text+0x18): undefined reference to `gum()'
main.cpp:(.text+0x24): undefined reference to `foo::bar() const'
collect2: error: ld returned 1 exit status
Вы можете определить gum
как inline
, если компилятор может видеть его определение в каждом исходном файле, в котором может быть вызвано gum
. Это означает, что его встроенное определение должно существовать в файле заголовка , который вы включаете в каждый исходный файл, который вы компилируете, в который может быть вызван gum
. Сделайте одно из двух:
Либо не включайте определения
Удалите спецификатор inline
из определения исходного файла:
foo.cpp (2)
#include "foo.h"
#include <iostream>
void foo::bar() const {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
gum.cpp (2)
#include "gum.h"
#include <iostream>
void gum()
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
Перестройте с этим:
$ g++ -c main.cpp foo.cpp gum.cpp
imk@imk-Inspiron-7559:~/develop/so/scrap1$ g++ -o prog main.o foo.o gum.o
imk@imk-Inspiron-7559:~/develop/so/scrap1$ ./prog
void gum()
void foo::bar() const
Успех.
Или правильно встроенный
Встроенные определения в заголовочных файлах:
foo.h (2)
#pragma once
#include <iostream>
struct foo {
void bar() const { // In-class definition is implicitly inline
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
// Alternatively...
#if 0
struct foo {
void bar() const;
};
inline void foo::bar() const {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
#endif
] gum.h (2)
#pragma once
#include <iostream>
inline void gum() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
Теперь нам не нужны foo.cpp
или gum.cpp
:
$ g++ -c main.cpp
$ g++ -o prog main.o
$ ./prog
void gum()
void foo::bar() const
Оказалось, что код, который я опубликовал в своем обновлении, был правильным, у меня только что была опечатка и один неверный параметр в строке данных.
string data = "{\"Header\":{\"AuthToken\":null,\"ProductID\":\"NOR\",\"SessToken\":null,\"Version\":1},\"ReturnAuthentication\":true,\"Password\":\"" + pwd + "\",\"Username\":\"" + uname + "\",\"ReturnCredentials\":true}";
Для простоты, почему бы вам не написать вызов веб-сервис на C # на стороне сервера?
У вас есть те же возможности для отправки запросов и получения ответов на C #, что и с Javascript.
Вот взлом вашей функции на C #:
public static string Authenticate(string pwd, string uname)
{
HttpWebRequest requestFile = (HttpWebRequest)WebRequest.Create("https://myHost.com/V1/Identity/Authenticate");
requestFile.ContentType = "application/json";
requestFile.Method = "POST";
StreamWriter postBody = new StreamWriter(requestFile.GetRequestStream())
using (postBody) {
postBody.Write("{\"Header\":{\"AuthToken\":null,\"ProductID\":\"NOR\",\"SessToken\":null,\"Version\":1},\"ReturnAuthentication\":true,\"Password\":\"" + pwd + "\",\"Username\":\"" + uname + "\",\"ReturnCredentials\":false }'");
}
HttpWebResponse serverResponse = (HttpWebResponse)requestFile.GetResponse();
if (HttpStatusCode.OK != serverResponse.StatusCode)
throw new Exception("Url request failed. Connection to the server inturrupted");
StreamReader responseStream = new StreamReader(serverResponse.GetResponseStream());
string ret = null;
using (responseStream) {
ret = responseStream.ReadLine();
}
return ret;
}
Отказ от ответственности Это не было проверено.
Похоже, вы столкнулись с той же политикой происхождения
http://en.wikipedia.org/wiki/Same_origin_policy
Я считаю, что есть способы обойти это, но я думаю, что другие плакаты правы. На сервере напишите методы, которые используют HttpWebRequest для вызова веб-службы, а затем используйте JavaScriptSerializer для анализа JSON. Я провел большую часть дня, исследуя эту причину, и мне придется написать что-то подобное самому.
>>>> Nathan
PS Мне больше нравится план @Janie ... Можете ли вы сделать это с помощью веб-службы, которая возвращает JSON, а также службу, которая пройдет назад XML?
Вместо использования клиентского сценария для выполнения запроса с сервера; используйте код на стороне сервера, чтобы сделать запрос
ИЗМЕНИТЬ, чтобы развернуть ответ:
В своем веб-проекте в Visual Studio нажмите «Добавить веб-ссылку» и укажите службу, к которой вы первоначально обращались через клиентский скрипт: (я считаю, что это was ' https://myHost.com/V1/Identity/Authenticate )
Теперь вы можете общаться со службой, используя код C # вместо js (и передавать учетные данные пользователей)
Кроме того, поскольку запрос к службе исходит от сервера, а не браузера; вы обходите применяемые междоменные ограничения.
ДАЛЬНЕЙШЕЕ ИЗМЕНЕНИЕ, чтобы показать дополнительную технику:
Если вам не нравится идея использования Visual Studio для создания прокси-сервера для вас, http://msdn.microsoft.com/en-us/library/system.net.webclient (VS.80) .aspx
HttpWebRequest: http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest (VS.80) .aspx