関数名の名前の衝突について

このQ&Aのポイント
  • 関数名の名前の衝突で困っています。Win32APIのGetFileSize関数を例に説明します。
  • 関数名の名前の衝突により、Win32APIのGetFileSize関数が利用できません。解決方法を教えてください。
  • 関数名の名前の衝突について困っています。UNICODEでマルチバイト版とで再定義する必要があるのでしょうか?
回答を見る
  • ベストアンサー

関数名の名前の衝突について。

こんにちは。 関数名の名前の衝突で困っています。 以下のような感じで名前空間でUNICODEでマルチバイト版とで定義しています。 Win32APIのGetFileSize関数を例に説明します。 Win32APIのGetFileSize関数はファイルハンドルを指定しなければいけないので 直接ファイル名からファイルサイズを取得できるように同じ名前の関数を 名前空間で区切って以下のようにしました。 ---------------- Foo.h -------------- #include <windows.h> namespace Foo { #ifdef UNICODE     #define GetFileSize GetFileSizeW #else     #define GetFileSize GetFileSizeA #endif // !UNICODE     DWORD GetFileSizeW( wchar_t* const szFilename ){ return 0 ;}     DWORD GetFileSizeA( char* const szFilename ){ return 0 ;} } ---------------- Foo.h -------------- 上記の関数はちゃんと動作することは確認できましたが、本来のWin32APIの DWORD GetFileSize( HANDLE hFile, LPDWORD lpFileSizeHigh ) を ---------------- main.cpp -------------- #include <windows.h> #include "Foo.h" void func( HANDLE hFile ) {     DWORD dwFilesize = ::GetFileSize( hFile, NULL ) ; } ---------------- main.cpp -------------- 上記のように利用しようとすると、 error C2039: 'GetFileSizeW' : '`global namespace'' のメンバではありません。 error C3861: 'GetFileSizeW': 識別子が見つかりませんでした というエラーが出てきてしまいます。 これを解決するためにはUNICODEでマルチバイト版とで再定義してしまっている #defineの部分を削除するしかないのでしょうか? もし解決方法がありましたら教えていただけないでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

 こんばんは。  tchar.hをインクルードして、LPCTSTR型を使用して見ては。 #include <windows.h> #include <tchar.h> namespace Foo { DWORD GetFileSize(LPCTSTR szFilename){ return 0; } } int main() { ::GetFileSize(hFile, NULL); Foo::GetFileSize(TEXT("ファイル名")); return 0; }  LPCTSTR型はUNICODEで「const wchar_t*」それ以外は「const char*」と成ります。  文字列を渡す時は、  Foo::GetFileSize(TEXT("testlog.txt"));  とし、バッファを渡す場合は、  TCHAR bufFilename[MAX_PATH + 1];//ファイル名が入っているとして  Foo::GetFileSize(bufFilename);  とします。  文字の操作は  _tcslen(bufFilename);//文字数を取る  の様にして、tchar.hの中にあるマクロを使用します。場合にもよりますが、上手くいけば「A」と「W」を作らずに、一つの関数で済ませる事も出来ます。

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

いずれにしても, 呼び出したい関数は Foo 名前空間にあるんだよね?

shuuden
質問者

補足

はい、Foo名前空間内にあります。 ただ、元の関数もたまに使います。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

C++を使うのであれば、 namespace Foo {  DWORD GetFileSize( wchar_t* const szFilename ){ return 0 ;}  DWORD GetFileSize( char* const szFilename ){ return 0 ;} } のように多重定義すればよいだけでは? ところで、wchar_t* constではなくwchar_t const*では?

shuuden
質問者

お礼

こんにちは。 言われてみれば全くその通りです。 このように記述すると、会社では言われていたのでそうしていました。 もうC++しかしか使っていないはずなので、週明けにでも聞いてみます。 ちなみに、wchar_t* const としているのは、関数内でポインタを変更させないためにしていました。 ありがとうございました。

shuuden
質問者

補足

こんにちは。 会社で聞いてみましたが、発注元の構文規約からきている風習だそうです。ご指摘ありがとうございました。

関連するQ&A

  • 他の.CPPファイルに定義した関数を呼び出す方法について

    新規作成したプロジェクトに、 以前自分が作成した.cppファイルと.hファイルを そのまま使えないかと考えています。 (※仮にそのファイルの名前を "define.cpp" "define.h" とします) プロジェクトに新規ファイル main.cpp を作成して、 define.hをインクルードし、 以下のようなテストのプログラムを組みました。 ・../util/define.cpp---------------------- #include <iostream> #include "define.h" void test(){ std::cout<<"test."<<std::endl; } ・../util/define.h------------------------ #pragma once void test(); ・main.cpp---------------------------- #include "../util/define.h" int main(){  test();  return 0; } 上記のソースを VisualC++7.0 でビルドすると、 main.cppの3行目で以下のようなエラーが出ました。 > LNK2019: 未解決の外部シンボル "void __cdecl test(void)" が関数 _main で参照されました VisualC++で「既存項目の追加」という項目より、 実体の定義されたdefine.cppをプロジェクトに追加していないため 当然といえば当然なのですが・・・ C言語でいうところの<stdio.h>等みたいに、 わざわざプロジェクトにCPPファイルを追加しなくても 関数を呼び出せるようには出来ないのでしょうか? 全ての関数と処理をヘッダーファイルに記述すると解決ですが 物凄く見辛いのでそれは避けたいのです。 また、色々なPC間で使っているため(学校のPCなので)、 ツール自体のプロパティを弄らない方法があるのでしたら、 多少面倒でもそちらの方が好ましいです。 追加する方法があるかどうか、 あればその方法をご存じでしたら教えていただければ嬉しいです。 よろしくお願いします。

  • [VC++]ヘッダファイルからの関数コール

    Formのボタンクリックイベント(Form.h)から 別ファイル(.cpp)の関数をコールしたいのですがうまくいきません、 どのようにすればよいでしょうか?ご教授お願いします。 1> : error C2144: 構文エラー : 'void' は ')' によって先行されなければなりません。 1> : error C2059: 構文エラー : ')' //----- main1.h #include <stdio.h> #include "Form1.h" namespace A { void main1(); } //----- main1.cpp #include <stdio.h> #include "main1.h" using namespace A; void main1() { //処理 } //----- Form1.h #include <stdio.h> #include "main1.h" void main1(void); namespace A { public ref class Form1 : public System::Windows::Forms::Form { public: private: System::Void btn_Click(System::Object^ sender, System::EventArgs^ e) { //★クリックイベントからmain1の関数コールしたい main1(void); } }; }

  • gdbで無名名前空間の関数にブレイクポイント

    Windows+cygwin+emacsでc++のプログラムを勉強しています。デバッガとしてemacs上でgdbを使っているのですが、無名の名前空間にある関数にブレイクポイントを設定する方法がわかりません。例えば、 namespace {  void foo() {    ...  } } int main(void) {  foo(); } のようなfoo.cppファイルをコンパイルしてfoo.exeファイルを作り、それをgdbによりデバッグするとします。そこで、gdb上で b main とすると、mainに入ったところにブレイクポイントが設定されますが、 b foo としても、Function "foo" not defined.と表示されてブレイクポイントが設定されません。無名の名前空間にある関数にはどのように入力してブレイクポイントを設定するのでしょうか。とりあえず、今は行番号によりブレイクポイントを設定しています。ご存じの方がいらっしゃいましたら、ご教授ください。お願いします。

  • namespace名前空間をヘッダファイル間で共用したい

    環境: WinXP, VisualStudio2005 目的: 現在WinAPI系のライブラリを作っているのですが、以下のような 状況で、namespaceを.cppファイルだけでなく.hファイルでも共用 出来るようにすることは可能でしょうか? ちなみに以下のコードでは lib.h(5) : error C2653: 'G' : 識別子がクラス名でも名前空間名でもありません。 lib.h(5) : error C2065: 'A' : 定義されていない識別子です。 というエラーが出てきます。 // main.h ---------------------------------------------------- #include "Global.h" int main() { } // Global.h --------------------------------------------------- #pragma once #include "Lib.h" namespace G { const int A = 100; } // Lib.h ------------------------------------------------------- #pragma once #include "Global.h" int b = G::A; //名前空間Gの中にあるAを代入

  • Visual C++ ヘッダー情報の反映

    ヘッダー内の定義(の変更)が反映されないことがあります。 例えば、 "stdafx.h"において #define a 123 と定義して、関数項目main.cppとfunc.cpp両方でaを使うとします。 もちろんどちらも最初に#include "stdafx.h"とインクルードしています。 ですがdefine定義を#define a 456のように変更し実行すると、 main.cpp内ではa=456で動作し、func.cpp内ではa=123で動作する。 というような症状がしばしば現れます。 Visual stadio 2008でプログラミングしています。 c++ 6.0のときも同様の症状が現れていたのですが、何か問題があるのでしょうか? よろしくお願いします。

  • 【VS2008 C++】2つのプロジェクト間で共通の関数を使いたい

    【VS2008 C++】2つのプロジェクト間で共通の関数を使いたい WindowsXP上で visual studio 2008 C++ express editionを 使用しています。 1つのソリューションに2つのプロジェクトをつくり、 その2つに共通の関数を使用させたいのですが、どのように 設定すればよいか教えて頂けませんでしょうか。 ソースの内容は以下のとおりです。 具体的には、mainB.cppでcommon.cppの関数を 呼び出したいです。 //common.cpp #include <stdio.h> void showCommon(){ printf("---common-----\n"); } //common.h #include<stdio.h> void showCommon(); //mainA.cpp #include<stdio.h> #include "common.h" void main(){ printf("---mainA-----\n"); showCommon(); } //mainB.cpp #include<stdio.h> #include "common.h" void main(){ printf("---mainB-----\n"); showCommon(); }

  • C++/CLI 関数がインポートできない

    Visual C++でビルドすると、 1>ConnectionWrapsTest.cpp(12): warning C4679: 'ConnectionWraps::Class1::GetConnection' : メンバーをインポートできませんでした 1> 型 'ConnectionWraps::Class1 ' をアセンブリ 'ConnectionWraps, Version=1.0.4594.40998, Culture=neutral, PublicKeyToken=null' からインポート中に、この診断が発生しました。 という様なエラーがいくつかでて、失敗してしまいます。 何故この様なエラーが出るのか理解出来ません。解決策を教えてください。 DLL側 ------------------------------------------- // ConnectionWraps.h #pragma once using namespace System; using namespace std; #include <string> namespace ConnectionWraps { public ref class Class1 { // TODO: このクラスの、ユーザーのメソッドをここに追加してください。 public: static int GetConnection(string address, string port, string database, string userid, string password); static void CloseConnection(int handle); static int ChangeDatabase(int handle, string databaseName); static int Command(int handle, string sql); }; } -------------------------------------------------- 実行ファイル側 ---------------------------------------------------- // ConnectionWrapsTest.cpp : メイン プロジェクト ファイルです。 #include "stdafx.h" #include <string> using namespace std; using namespace System; using namespace ConnectionWraps; int main(array<System::String ^> ^args) { Console::WriteLine(Class1::GetConnection("a", "a", "a", "a", "a", "a")); return 0; } -------------------------------------------------

  • 外部ファイルでのtemplate関数の実装方法

    外部ファイルでのtemplate関数の実装方法 sub.cppにtemplate関数を実装し、 main.cppで、sub.cppのtemplate関数を呼び出す、 みたいなことをやりたいのですが、 コンパイルは通りますが、リンクエラー?になってしまいます。 以下が上記のサンプルプログラムです。 //main.cpp #include <vector> #include <iostream> using namespace std; template <typename t_ret, typename t_array> t_ret sub_t(const t_array&); int main (int argc, char *argv[]) { vector<double> v; v.push_back(1.1); v.push_back(2.2); cout << sub_t<double, vector<double> >(v) << endl; return 0; } // sub.cpp #include <vector> using namespace std; template <typename t_ret, typename t_array> t_ret sub_t(const t_array& array) { return array[0]+array[1]; } //コンパイルログ main.o: In function `main': main.cpp:(.text+0x134): undefined reference to `double sub_t<double, std::vector<double, std::allocator<double> > >(std::vector<double, std::allocator<double> > const&)' collect2: ld returned 1 exit status make: *** [main] Error 1 どなたか、対処方法を教えてください。 宜しくお願いします。

  • C++でConvertSidToStringSid関数を使うために、sddl.hを使用したい

    お世話になります。 現在C++ 6.0でソフトを作成しています。 その中でConvertSidToStringSid関数を使うために、sddl.hを使用したいのですが、下記のようなエラーが出ます。 -----------インクルード------------------ #include <stdlib.h> #pragma comment(lib,"netapi32.lib") //////////ここで定義しているつもりです。 #define _WIN32_WINNT 0x0500 #include <windows.h> #include <sddl.h> //////////ここで定義しているつもりです。 #include <tchar.h> #include <lmaccess.h> #include <lmapibuf.h> #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ----------デバックエラー J:\Del.cpp(17) : fatal error C1083: インクルード ファイルがオープンできません。'sddl.h': No such file or directory どのようにすればConvertSidToStringSid関数を使うために、sddl.hを使用できますでしょうか? 何卒よろしくお願いします。

  • critical error c0000005

    Visual C++ 2012 でファイルにデータを書き込む処理を組んでみた所、アプリケーション側にて下記のエラーが出てきます。 [Application side] -- log --------- function 'FuncTest' call from dll 'Test.dll' critical error c0000005 at 77D3F44D. ---------------- Test.cpp内の※1をコメントアウトすると、取り敢えずはエラーは発生しないのですが、どこが間違っているのかがわかりません。 よろしくお願いします。 下記は、VC++のソース部分です。 [Source of C++] --- Test.h ----- #define Test_API __declspec(dllexport) Test_API void WINAPI FuncTest(void); ---------------- --- Test.cpp --- #include "stdafx.h" #include "Test.h" Test_API void WINAPI FuncTest(void) { HANDLE hFile = NULL; __try { _EXCEPTION_POINTERS ep = {NULL}; __try { CHAR filePath[MAX_PATH]; sprintf(filePath, "filename.csv"); hFile = CreateFileA(fileName, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); <--- (※1) if(hFile == INVALID_HANDLE_VALUE) throw; ...(snip) } __except (ep = *GetExceptionInformation(), EXCEPTION_EXECUTE_HANDLER) {) { PEXCEPTION_RECORD per = ep.ExceptionRecord; CHAR eBuff[1024]; sprintf_s(eBuff, 1024, "%d (code:%x flag:%x addr:%p params:%d)", err, eRec->ExceptionCode, eRec->ExceptionFlags, eRec->ExceptionAddress, eRec->NumberParameters); free(eRec); MessageBoxA(NULL, eBuff, "FuncTest Error!", MB_OK); } } __finally { CloseHandle(hFile); } } ---------------- --- Test.def --- LIBRARY Test EXPORTS FuncTest ----------------

専門家に質問してみよう