トップ回答者
"ネイティブのC++プログラム”とはどういう意味ですか?

質問
-
私は極最近Windowsプログラムを始めた初心者でお恥ずかしい質問です。
ms-help://MS.VSExpressCC.v80/MS.NETFramework.v20.ja/dv_vcmcpp/html/b200cfd1-0440-498f-90ee-7ecf92492dc0.htm
方法 : ネイティブの C++ プログラムをコマンドラインからコンパイルする
・・・にあるC++プログラムで、次に示すものは”ネイティブの C++ プログラム”と書かれていますが、
ここで”ネイティブのC++プログラム”とはどういう意味ですか?#include <iostream>
int main()
{
std::cout << "This is a native C++ program." << std::endl;
return 0;
}Nativeは文字通りには、”固有”という意味ですが、”ネイティブのC++プログラム”の本質的意味が
理解できないでおります。また、VisualC++ Express Edition では"Win32コンソールアプリケーション"と、"CLRコンソールアプリケーション"が
プロジェクト生成できますが、同じコンソール応用プログラムであっても、それぞれの意味や構造はどのように違いますか?
よろしくお願いします。
回答
-
dimension さんからの引用 ここで”ネイティブのC++プログラム”とはどういう意味ですか?
ここで言う「ネイティブ」は、「実行形式ファイルを OS がメモリに読み込み、CPU が直接的に解釈・実行を行う」スタイルを指しています。
「ネイティブ~」は、このスタイルに対応した事物を指し示す場合の枕詞になっています。
古来、このスタイルが主流であり、これらの実行環境や方式をあえて「ネイティブ」と呼ぶことはありませんでした。
しかしながら近年、Java や .NET のような、OS とは異なる層でアプリケーションプログラムの解釈・実行を行う「仮想実行環境」が登場し、混乱を避ける意味からも、両者を区別する語が必要となる場面がチラホラ見られはじめました。
そこで、特に Microsoft 社では、.NET の仮想実行環境(=.NET ランタイム = CLR)の管理下でプログラム実行を行うスタイルを「マネージ(ド)」と呼び、旧来の OS/CPU 手動でプログラム実行するスタイルを「ネイティブ」と呼ぶことにしたようです。
-
dimension さんからの引用 .NETクラス・ライブラリを使うプログラムを”マネージ(ド)”なプログラムと呼び、そうでない旧来のOS/CPU 手動でプログラム実行するスタイルを”ネイティブ”なプログラムと呼ぶこと・・・と理解しました。
「.NET クラスライブラリの使用の有無」が切り分けのポイントではありません。
「実行の方式」の違いが重要なポイントです。前述のように、「.NET ランタイム(=CLR)が実行形式の読み込みと解釈・実行を行われる」スタイルを(主にマイクロソフトが)「マネージ」と呼び、それと区別する意味で、旧来のスタイルを「アンマネージ」や「ネイティブ」と呼んでいます。
「ランタイムライブラリ」なんて語もあるので、ランタイムとライブラリの区別が難しいかもしれませんが、.NET ではかなり明確に区別されています。
ここで言う「ランタイム」は、Java の VM に相当するものと考えてもらっても間違いではありません。dimension さんからの引用 そう解釈すると、具体的に質問するのために私が持ち出したWinsock2.0ライブラリを使うWin32コンソールアプリケーションは、.NETクラスの関数を使っていないので”Native”なC言語プログラム・・・と解釈しました。
そうです。おそらくは「C 言語または C++ 言語で記述されたネイティブなプログラム」です。
ですが、これも前述したように、VC++ は C/C++ 言語に両対応であるため、ソースコードだけから「C 言語」と「 C++ 言語」のどちらのコンパイラ(のモード)が使用されたかは判断できません。
(ソースファイルの拡張子やコンパイルオプションなどによって変化します)
すべての返信
-
dimension さんからの引用 また、VisualC++ Express Edition では"Win32コンソールアプリケーション"と、"CLRコンソールアプリケーション"が
プロジェクト生成できますが、同じコンソール応用プログラムであっても、それぞれの意味や構造はどのように違いますか?
よろしくお願いします。http://www.microsoft.com/japan/msdn/netframework/programming/clr/
が参考になります。
CLRコンソールアプリケーションは、共通言語ランタイムが解釈、実行する形で動作します。「ランタイム環境でない」アプリケーションをネイティヴアプリケーションと呼んでいるのでしょう。
-
じゃんぬねっとさん、sakamotoさん、アドバイスをありがとうございます。
ちょっとまだわからないので、とりあえず”Win32コンソールアプリケーション”でプロジェクトを新規生成して、
Winsock2.0を使ったコンソールプログラムができるかどうか試してみました。以下、”Windows編NO2 お題「ネットワークプログラミング入門」”
http://www.stylefree.net/main/nprogramming/windows/windows2.shtml
から引用します。//プログラム名 HttpDataGet
#include <winsock2.h>
#include <stdio.h>
#include <conio.h>int main( int argc, char *argv[])
{
WSADATA wsadata;
WORD wversion = WINSOCK_VERSION;
SOCKET s;
struct sockaddr_in serv;
struct hostent *host;
char server_name[255];
char recv_buffer[4096];
int nError;//Winsock.dllを初期化
nError = WSAStartup( wversion, &wsadata);
if( nError) {
fprintf( stderr, "WSAStartup error\n");
return 0;
}
//Winsockのバージョンをチェック
if( wversion != wsadata.wVersion) {
fprintf( stderr, "Winsock version error\n");
return 0;
}
//ソケットオープン
if( ( s = socket( AF_INET, SOCK_STREAM, 0)) < 0) {
fprintf( stderr, "Socket open error\n");
return 0;
}
//サーバー名入力
printf( "Server name -> ");
scanf( "%s", server_name);
//DNS名前解決(サーバーのIPアドレスを割り出す)
if( ( host = gethostbyname( server_name)) == NULL) {
unsigned long addr;
addr = inet_addr( server_name);
if( ( host = gethostbyaddr( (char *)&addr, sizeof( addr), AF_INET)) == NULL) {
fprintf( stderr, "Server none\n");
return 0;
}
}
//各種設定
memset( &serv, '\0', sizeof( serv));
serv.sin_family = AF_INET;//アドレスファミリーを指定
memcpy( &serv.sin_addr, host->h_addr, host->h_length);//接続先IPアドレス指定
serv.sin_port = htons( 80);//接続先ポート番号指定
//接続
if( connect( s, (struct sockaddr *)&serv, sizeof( serv)) < 0) {
fprintf( stderr, "Connect error\n");
return 0;
}
//データを送信(要求)
if( send( s, "GET\r\n", strlen( "GET\r\n"), 0) < 0) {
fprintf( stderr, "Send error\n");
return 0;
}
//データを受信(応答)
if( ( nError = recv( s, recv_buffer, sizeof( recv_buffer), 0)) < 0) {
fprintf( stderr, "Recv error\n");
return 0;
}
recv_buffer[nError] = '\0';
//応答データを表示
printf( "Recv data\n-------------------------------------\n"
"%s\n-------------------------------------\nExit data\n",
recv_buffer);
//キー入力(出力を眺めるため)
printf( "Please enter key");
getch();
//ソケットクローズ
closesocket( s);
//Winsock後処理
WSACleanup();
return 0;
}------------------------------------------
上のプログラムは次の問題がありました。、(1)指定したhttpサーバから、一回のGETメソッドのリクエストに対し送信されてくるデータを
全部受信できていない。
(2)recv_buffer[nError] = '\0'; が、同配列を1バイトメモリ越境してアプリケーションエラーになる。これをVisualC++ Express Edition用に次のように改良しました。
(1)’指定したhttpサーバから、一回のGETメソッドのリクエストに対し送信されてくるデータを
全部受信する。
(2)’recv_buffer[nError] = '\0'; が、同配列を1バイトメモリ越境する問題を対策。---stdafx.h---
// stdafx.h : 標準のシステム インクルード ファイルのインクルード ファイル、または
// 参照回数が多く、かつあまり変更されない、プロジェクト専用のインクルード ファイル
// を記述します。
//#pragma once
#define WIN32_LEAN_AND_MEAN // Windows ヘッダーから使用されていない部分を除外します。
#include <stdio.h>
#include <tchar.h>// TODO: プログラムに必要な追加ヘッダーをここで参照してください。
#pragma comment( lib, "ws2_32.lib" )
#include <winsock2.h>
#include <conio.h>---end of stdafx.h---
---stdafx.cpp---
// stdafx.cpp : 標準インクルード gethttp.pch のみを
// 含むソース ファイルは、プリコンパイル済みヘッダーになります。
// stdafx.obj にはプリコンパイル済み型情報が含まれます。#include "stdafx.h"
// TODO: このファイルではなく、STDAFX.H で必要な
// 追加ヘッダーを参照してください。---end of stdafx.cpp--
---gethttp.cpp---
// gethttp.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
//プログラム名 HttpDataGetWSADATA wsadata;
WORD wversion = WINSOCK_VERSION;
SOCKET s;
struct sockaddr_in serv;
struct hostent *host;
char server_name[255];
char recv_buffer[4097];
int nError;//Winsock.dllを初期化
nError = WSAStartup( wversion, &wsadata);
if( nError) {
fprintf( stderr, "WSAStartup error\n");
return 0;
}
//Winsockのバージョンをチェック
if( wversion != wsadata.wVersion) {
fprintf( stderr, "Winsock version error\n");
return 0;
}
//ソケットオープン
if( ( s = socket( AF_INET, SOCK_STREAM, 0)) < 0) {
fprintf( stderr, "Socket open error\n");
return 0;
}
//サーバー名入力
printf( "Server name -> ");
scanf( "%s", server_name);
//DNS名前解決(サーバーのIPアドレスを割り出す)
if( ( host = gethostbyname( server_name)) == NULL) {
unsigned long addr;
addr = inet_addr( server_name);
if( ( host = gethostbyaddr( (char *)&addr, sizeof( addr), AF_INET)) == NULL) {
fprintf( stderr, "Server none\n");
return 0;
}
}
//各種設定
memset( &serv, '\0', sizeof( serv));
serv.sin_family = AF_INET;//アドレスファミリーを指定
memcpy( &serv.sin_addr, host->h_addr, host->h_length);//接続先IPアドレス指定
serv.sin_port = htons( 80);//接続先ポート番号指定
//接続
if( connect( s, (struct sockaddr *)&serv, sizeof( serv)) < 0) {
fprintf( stderr, "Connect error\n");
return 0;
}
//データを送信(要求)
if( send( s, "GET\r\n", strlen( "GET\r\n"), 0) < 0) {
fprintf( stderr, "Send error\n");
return 0;
}
//データを受信(応答)
while ( (nError = recv( s, recv_buffer, sizeof(recv_buffer)-1, 0)) > 0)
{
recv_buffer[nError] = '\0';
//応答データを表示
printf( "//Recv data\n-------------------------------------\n"
"%s\n-------------------------------------\nStopped at recv()\n",
recv_buffer);
//キー入力(出力を眺めるため)
printf( "//Please enter key to recv next data!\n");
getch();
}if ( nError < 0)
{
fprintf( stderr, "//Recv error!!\n");
goto END ;
}
if ( nError == 0)
printf("//Recv ended OK!!\n");END:
//ソケットクローズ
closesocket( s);
//Winsock後処理
WSACleanup();
return 0;}
--- end of gethttp.cpp ---
・・・このプログラムは、"Win32コンソールアプリケーション”として
プロジェクトを新規作成しました。質問:
このプログラムは、”Native”なC言語プログラムでしょうか?
-
ネイティブなC、ネイティブなC++などのいろいろな用語が使われていますね。
私は次のように解釈しております。
「ネイティブなCプログラム」とは
C言語で記述され、Cランタイムエンジンで解釈実行されるもの
「ネイティブなC++プログラム」とは、
C++言語で記述され、C++ランタイムエンジンで解釈実行されるもの
「C#/VB.NETプログラム」とは
C#言語で記述され、CLR(common language runtime)ランタイムエンジンで解釈実行されるもの
Microsoft社にはそれぞれのエンジンを開発するチームがあるようです。ただし、言語的には、Cへの需要があまりないため、C++エンジンを優先開発しているといわれています。「C++はCのスーパーセット」といわれています。
参考になれば幸いです。豊田孝 -
Takashi SAKAMOTO さんからの引用 dimension さんからの引用 質問:
このプログラムは、”Native”なC言語プログラムでしょうか?.NET Runtime 上で動作しているアプリケーション(.EXE)かどうかのチェックには、Dependency Walker に EXE を食べさせて mscoree.dll に依存しているかどうかを見れば(取り敢えず)判別できると思いますけど…。
#そういう問題…ではないのでしょうか?
こんにちはRESありがとうございます。
プログラム作成完了後に、プログラムの種別(NativeなC/C++かどうか)を判別したいのではなく、一番最初の質問を補足すると、
・NativeなC++プログラムの意味を、知識として知っておきたいのです。
(1)例えば、前記事の例で書いた標準ライブラリ、WInsock2.0ライブラリを使ったWin32コンソールアプリケーションは、NativeなC/C++プログラムなのでしょうか?
(2)標準ライブラリだけを使用したC/C++プログラムが、NativeなC/C++プログラムなのでしょうか?
(3)コンソールプログラムでも、.NET(CLI)ライブラリを使用したプログラムは、Nativeなものとは言わないのでしょうか?
・・・要するに
・”Native”の意味する言葉の意味そのものがわからないのと、
・プログラムの使用するライブラリに関係して、どういうライブラリを使う/または使わないプログラムをNativeと言うのかわからない。
ということなのですが、質問の意図を伝えるよう努力しているところです。
-
Takashi Toyota さんからの引用 「ネイティブなCプログラム」とは
C言語で記述され、Cランタイムエンジンで解釈実行されるもの
「ネイティブなC++プログラム」とは、
C++言語で記述され、C++ランタイムエンジンで解釈実行されるものC ランタイムエンジン、C++ ランタイムエンジンなんてものはありません。
(少なくとも VC++ には含まれていません)一般に、「C ランタイム」「C++ ランタイム」と呼ばれるものは、実行形式に動的または静的にリンクされる、単なるライブラリです。
大多数の C\C++ 処理系は、C/C++ で記述されたプログラムを「コンパイル」「リンク」といった操作によって、特定のOSで実行可能な実行形式(=これを「XXOSのネイティブ実行形式」と呼びます)を生成します。
実行形式は「ランタイムエンジン」によって解釈実行されるのではなく、OSによってCPUのメモリ空間に読み込まれ(必要なら再配置が行われ)て、CPUが直接的に解釈実行を行います。
-
dimension さんからの引用 ここで”ネイティブのC++プログラム”とはどういう意味ですか?
ここで言う「ネイティブ」は、「実行形式ファイルを OS がメモリに読み込み、CPU が直接的に解釈・実行を行う」スタイルを指しています。
「ネイティブ~」は、このスタイルに対応した事物を指し示す場合の枕詞になっています。
古来、このスタイルが主流であり、これらの実行環境や方式をあえて「ネイティブ」と呼ぶことはありませんでした。
しかしながら近年、Java や .NET のような、OS とは異なる層でアプリケーションプログラムの解釈・実行を行う「仮想実行環境」が登場し、混乱を避ける意味からも、両者を区別する語が必要となる場面がチラホラ見られはじめました。
そこで、特に Microsoft 社では、.NET の仮想実行環境(=.NET ランタイム = CLR)の管理下でプログラム実行を行うスタイルを「マネージ(ド)」と呼び、旧来の OS/CPU 手動でプログラム実行するスタイルを「ネイティブ」と呼ぶことにしたようです。
-
dimensionさんの疑問点は次の点にあるようです。
・プログラムの使用するライブラリに関係して、どういうライブラリを使う/または使わないプログラムをNativeと言うのかわからない。
一番簡単な方法は、C、C++、C#でHellow Worldプログラムを作成し、デバッグ環境でブレークポイントを設定してはいかがでしょうか。動作が停止した時点で、ロードされているモジュールを眺めてください(このような便利な機能があります)。
Microsoft社は、ロードされるモジュールの説明として、ライブラリ、DLL、EE(実行エンジン)などの用語を使ってそれぞれのモジュールを説明してくれています。表示されるモジュールリストを見れば、何らかのヒントが得られると思います。 -
面白そうなので、ご紹介のソースコードを「空のWin32コンソールプロジェクト」としてビルドしてみました。
そのままビルドした場合には、NativeなC言語プログラムといってよいのではないでしょうか。
しかし、<iostream>などを追加インクルードしてビルドすると、CとC++のハイブリッドプログラムになると思います。
なお、Windowsアプリケーションにも「Nativeアプリケーション」と呼ぶべきプログラムがあるようです。詳細は次のページを参照してください。
Inside Native Application
面白いですね。 -
Takashi Toyota さんからの引用 豊田です。
dimensionさんはここまでの説明を求めていらっしゃるのでしょうか?求めていると思います。
元投稿者の人は、VC++ プロジェクトの表記に出てくる「ネイティブ」という用語が何を指しているのかをたずねていると思います。
この場合の「ネイティブ」は Windows OS のことであり、対になる語は「マネージ」あるいは CLR であると思います。
私は、CとC++の違いのようなものをお知りになりたいのでは?、と解釈いたしました。仮にそうだとするなら、違いは明確です。
C 言語仕様、C++ 言語仕様はそれぞれ ISO スタンダードになっていますから、それぞれの言語仕様で定められた仕様の違いが両言語の違いです。出典の怪しげな「C ランタイムエンジン」「C++ ランタイムエンジン」等を持ち出す必要があるとは思えません。
dimensionさんは、ご自分が入力されたソースコードが最終的に「ネイティブC」か「ネイティブC++」のいずれかに解釈・実行されるのかどうか、という点を理解されたいのではないでしょうか?VC++ は C/C++ 言語のコンパイラが一本化されているので、その視点での厳密な切り分けは難しいです。
-
渋木宏明 さんからの引用 dimension さんからの引用 ここで”ネイティブのC++プログラム”とはどういう意味ですか?
ここで言う「ネイティブ」は、「実行形式ファイルを OS がメモリに読み込み、CPU が直接的に解釈・実行を行う」スタイルを指しています。
「ネイティブ~」は、このスタイルに対応した事物を指し示す場合の枕詞になっています。
古来、このスタイルが主流であり、これらの実行環境や方式をあえて「ネイティブ」と呼ぶことはありませんでした。
しかしながら近年、Java や .NET のような、OS とは異なる層でアプリケーションプログラムの解釈・実行を行う「仮想実行環境」が登場し、混乱を避ける意味からも、両者を区別する語が必要となる場面がチラホラ見られはじめました。
そこで、特に Microsoft 社では、.NET の仮想実行環境(=.NET ランタイム = CLR)の管理下でプログラム実行を行うスタイルを「マネージ(ド)」と呼び、旧来の OS/CPU 手動でプログラム実行するスタイルを「ネイティブ」と呼ぶことにしたようです。
正確な解説をありがとうございました。
.NETクラス・ライブラリを使うプログラムを”マネージ(ド)”なプログラムと呼び、そうでない旧来のOS/CPU 手動でプログラム実行するスタイルを”ネイティブ”なプログラムと呼ぶこと・・・と理解しました。
そう解釈すると、具体的に質問するのために私が持ち出したWinsock2.0ライブラリを使うWin32コンソールアプリケーションは、.NETクラスの関数を使っていないので”Native”なC言語プログラム・・・と解釈しました。
-
dimension さんからの引用 通りには、”固有”という意味ですが、”ネイティブのC++プログラム”の本質的意味が
理解できないでおります。また、VisualC++ Express Edition では"Win32コンソールアプリケーション"と、"CLRコンソールアプリケーション"が
プロジェクト生成できますが、同じコンソール応用プログラムであっても、それぞれの意味や構造はどのように違いますか?
よろしくお願いします。不正確なのを覚悟の上で簡単に言えば、「ネイティブ」とは「Win32ナントカ」っていうプロジェクトで生成したアプリケーション、「マネージ(ネイティブでない)」とは「CLRナントカ」っていうプロジェクトで生成したアプリケーションのことです。
-
渋木さん、アドバイスありがとうございます。
いくつか補足させてください。
・この場合の「ネイティブ」は Windows OS のことであり、対になる語は「マネージ」あるいは CLR であると思います。
その通りです。この場合、CPUは関係ありません。
・C 言語仕様、C++ 言語仕様はそれぞれ ISO スタンダードになっていますから、それぞれの言語仕様で定められた仕様の違いが両言語の違いです。
dimensionさんが疑問とされているのは、「Native C program」と「Native C++ program」の構造上の違いかと思います。私の表現も少しおかしいのですが、組み込まれるライブラリなどの違いなのではないでしょうか。この面での回答はすでに公開しておりますから、省略いたします。
・出典の怪しげな「C ランタイムエンジン」「C++ ランタイムエンジン」等を持ち出す必要があるとは思えません。
用語使用面で誤解を与えたことをお詫びいたします。ただ、私は、「Native C program」と「Native C++ program」の構造上の違いはこの面に現れのではないかと考えております。
CLRはmscoree.dllとして実装され、この場合の「ee」はExecution Engineであり、この用語に支配されました。「C ランタイムエンジン」「C++ ランタイムエンジン」は実装機能上の表現であり、出典はございません。ユー***ードが上位コードを受け取り、それを解釈し、下位のエグゼキュティブコードを呼び出すようなものです。
混乱を与え大変申し訳ありません。
・VC++ は C/C++ 言語のコンパイラが一本化されているので、その視点での厳密な切り分けは難しいです。
スイッチがあり、それほど難しいものでしょうか?切り分けが難しいのは、「C++がCの文化を可能な限り踏襲している」背景だと思います。
型という視点から見ると、両者はかなり違う印象を受けております。私はオープンソースのアプリをビルドしながら利用することがありますが、その際には、CとC++の切り分けスイッチを活用しています。また、活用しないとビルドできないことが結構あります。 -
dimension さんからの引用 私は極最近Windowsプログラムを始めた初心者でお恥ずかしい質問です。
ms-help://MS.VSExpressCC.v80/MS.NETFramework.v20.ja/dv_vcmcpp/html/b200cfd1-0440-498f-90ee-7ecf92492dc0.htm
方法 : ネイティブの C++ プログラムをコマンドラインからコンパイルする
・・・にあるC++プログラムで、次に示すものは”ネイティブの C++ プログラム”と書かれていますが、
ここで”ネイティブのC++プログラム”とはどういう意味ですか?#include <iostream>
int main()
{
std::cout << "This is a native C++ program." << std::endl;
return 0;
}Nativeは文字通りには、”固有”という意味ですが、”ネイティブのC++プログラム”の本質的意味が
理解できないでおります。また、VisualC++ Express Edition では"Win32コンソールアプリケーション"と、"CLRコンソールアプリケーション"が
プロジェクト生成できますが、同じコンソール応用プログラムであっても、それぞれの意味や構造はどのように違いますか?
よろしくお願いします。
この文面を改めて拝読しますと、次のような解釈が可能です。
Native!="固有"。たとえば、Native English speakerという場合、英語を母国語として話す人、という意味です。ここから、Native C++ Programはプログラミング言語C++で記述されたプログラム、Native C Programはプログラミング言語Cで記述されたプログラムの意味でしょう。さらにいえば、Native Managed C++(CLR対応言語) Programはプログラミング言語マネージドC++で記述されたプログラムということになると思います。結果的に、出来上がるプログラムには"意味や構造はどのように違い"が出る、ということになると思います。意味や構造上の違いは、皆さんの説明通りです。
皆様、お疲れ様でした。 -
dimension さんからの引用 .NETクラス・ライブラリを使うプログラムを”マネージ(ド)”なプログラムと呼び、そうでない旧来のOS/CPU 手動でプログラム実行するスタイルを”ネイティブ”なプログラムと呼ぶこと・・・と理解しました。
「.NET クラスライブラリの使用の有無」が切り分けのポイントではありません。
「実行の方式」の違いが重要なポイントです。前述のように、「.NET ランタイム(=CLR)が実行形式の読み込みと解釈・実行を行われる」スタイルを(主にマイクロソフトが)「マネージ」と呼び、それと区別する意味で、旧来のスタイルを「アンマネージ」や「ネイティブ」と呼んでいます。
「ランタイムライブラリ」なんて語もあるので、ランタイムとライブラリの区別が難しいかもしれませんが、.NET ではかなり明確に区別されています。
ここで言う「ランタイム」は、Java の VM に相当するものと考えてもらっても間違いではありません。dimension さんからの引用 そう解釈すると、具体的に質問するのために私が持ち出したWinsock2.0ライブラリを使うWin32コンソールアプリケーションは、.NETクラスの関数を使っていないので”Native”なC言語プログラム・・・と解釈しました。
そうです。おそらくは「C 言語または C++ 言語で記述されたネイティブなプログラム」です。
ですが、これも前述したように、VC++ は C/C++ 言語に両対応であるため、ソースコードだけから「C 言語」と「 C++ 言語」のどちらのコンパイラ(のモード)が使用されたかは判断できません。
(ソースファイルの拡張子やコンパイルオプションなどによって変化します) -
Takashi Toyota さんからの引用
dimensionさんが疑問とされているのは、「Native C program」と「Native C++ program」の構造上の違いかと思います。元投稿者の人の最新のコメントを見る限り、そうではないように思います。
そもそも「ネイティブ C」や「ネイティブ C++」という語は一般的な用語なんでしょうか?
Managed C++ なら知っていますが、それらの語はあまり目にした記憶がありません。Manged C++ を話題にしている時、便宜上 Native C++ という語を使うことはあるかも知れませんが、Managed C なんてものが存在しない(ですよね?)以上、Native C なんて語も存在しないはずです。
Microsoft 的には Managed の対語として Native を使っていますが、Microsoft 的な Managed とは無関係に Native という語を持ち出す場合、何に対する "Native" なのでしょうか?
Takashi Toyota さんからの引用
ただ、私は、「Native C program」と「Native C++ program」の構造上の違いはこの面に現れのではないかと考えております。現れていません。
VC++ が出力する .exe, .dll は Windows OS が規定する実行形式です。コンパイラ設計の過程で EE (Excution Engine)というものが想定されることがあるのかもしれませんが、少なくとも VC++ で作成された「ネイティブな」実行形式を Windows が実行するプロセスは Windows OS に固有のものであり、C/C++ 言語仕様の影響はまったく受けていません。
Windows の実行形式の実行プロセスについてキチンと調べてみてください。
Takashi Toyota さんからの引用
私の表現も少しおかしいのですが、組み込まれるライブラリなどの違いなのではないでしょうか。Takashi Toyota さんからの引用
スイッチがあり、それほど難しいものでしょうか?切り分けが難しいのは、「C++がCの文化を可能な限り踏襲している」背景だと思います。ソースコードの記述がどの言語仕様に則っているのかという事と、生成された実行形式がどんなものかという話がごっちゃになってませんか?
私が「難しい」としたのは、C 言語仕様内で記述されたソースコードを C++ 言語コンパイラでコンパイルすることは可能なので、どのコンパイラ(のモード)で実行形式が作成されたかをソースコードから判別することは難しいですよね?ということです。
-
渋木宏明 さんからの引用 dimension さんからの引用 .NETクラス・ライブラリを使うプログラムを”マネージ(ド)”なプログラムと呼び、そうでない旧来のOS/CPU 手動でプログラム実行するスタイルを”ネイティブ”なプログラムと呼ぶこと・・・と理解しました。
「.NET クラスライブラリの使用の有無」が切り分けのポイントではありません。
「実行の方式」の違いが重要なポイントです。前述のように、「.NET ランタイム(=CLR)が実行形式の読み込みと解釈・実行を行われる」スタイルを(主にマイクロソフトが)「マネージ」と呼び、それと区別する意味で、旧来のスタイルを「アンマネージ」や「ネイティブ」と呼んでいます。
「ランタイムライブラリ」なんて語もあるので、ランタイムとライブラリの区別が難しいかもしれませんが、.NET ではかなり明確に区別されています。
ここで言う「ランタイム」は、Java の VM に相当するものと考えてもらっても間違いではありません。dimension さんからの引用 そう解釈すると、具体的に質問するのために私が持ち出したWinsock2.0ライブラリを使うWin32コンソールアプリケーションは、.NETクラスの関数を使っていないので”Native”なC言語プログラム・・・と解釈しました。
そうです。おそらくは「C 言語または C++ 言語で記述されたネイティブなプログラム」です。
ですが、これも前述したように、VC++ は C/C++ 言語に両対応であるため、ソースコードだけから「C 言語」と「 C++ 言語」のどちらのコンパイラ(のモード)が使用されたかは判断できません。
(ソースファイルの拡張子やコンパイルオプションなどによって変化します)夜分遅くに誠意あるご回答をありがとうございました。
Vertial Machineの考え方と仕掛けが.NETにあるとは思いもよらない新知識となりました。.NETは新しく整理されたWIndowsOSと連携する関数ライブラリと考えていたのは私の思い込みで誤りでした。ご教示をありがとうございました。
-
Vertial Machineの考え方と仕掛けが.NETにあるとは思いもよらない新知識となりました。大人の事情もあってでしょうが、はっきり "VM" という言葉を使って説明しているのはあまり見かけませんが、.NET ランタイム(=CLR)が拠り所としている CLI 仕様の根底に流れる考え方は Java VM のそれに通じるものがあります。
ユーザプログラムの実行・解釈の主導権をOSより上の層で行うことよって、セキュリティ強化など、特に近年重要視されているいくつかの恩恵を得ることが出来るためです。
.NETは新しく整理されたWIndowsOSと連携する関数ライブラリと考えていたのは私の思い込みで誤りでした。もちろん、そういう面もあります。
.NET 3.0 では、CLR は .NET 2.0 相当のまま据え置きで、標準クラスライブラリの大幅な拡充が図られています。
-
渋木さん、ご返信ありがとうございます。
ずいぶんな盛り上がりです。お尋ねの件にのみご返信申し上げます。
・Microsoft 的には Managed の対語として Native を使っていますが、Microsoft 的な Managed とは無関係に Native という語を持ち出す場合、何に対する "Native" なのでしょうか?
Native CやNative C++は、Manged に対する、あくまでも便宜上の表現でしょう。私はこの文脈の中で使用しています。厳密に言えば、そのような表現は可能でしょうが、一般的ではないと思います。Stroustrup氏は、"C++を学習する前にCを学ぶ必要はない。C++にはそれ本来の考え方があり、それさえ学んでもらえばよい"と述べています。もちろん、SmallTalkも学ぶ必要はない、とも述べています。この主張を考慮すると、同氏の考え(Native C++)を心底理解している人はいないのではないでしょうか。Managedに対するNative、という単純な図式でよいと思います。
・現れていません。VC++ が出力する .exe, .dll は Windows OS が規定する実行形式です。
私が述べている「構造上」とは、モジュール構成です。質問者は「どのようなライブラリを使うと...」という疑問をお持ちです。ライブラリの使い方により、モジュール構成は変わります。この点での確認手順はすでに述べたとおりです。また、Windows OSが規定する実行形式はPEであり、この点は私も熟知しております。ただ、この質疑応答には関係ないでしょう。
・コンパイラ設計の過程で EE (Excution Engine)というものが想定されることがあるのかもしれませんが、少なくとも VC++ で作成された「ネイティブな」実行形式を Windows が実行するプロセスは Windows OS に固有のものであり、C/C++ 言語仕様の影響はまったく受けていません。
少し論点がずれているようです。上記の回答を再読してください。実行プロセスを調査するのでしたら、MicrosoftのTechnical Fellowに就任されたRussinovich氏のAutorunが使えます。ただし、これもこの質疑応答には関係ありません。
・私が「難しい」としたのは、C 言語仕様内で記述されたソースコードを C++ 言語コンパイラでコンパイルすることは可能なので、どのコンパイラ(のモード)で実行形式が作成されたかをソースコードから判別することは難しいですよね?ということです。
これも論点がずれています。ソースコードを書いた人は、そのコードを記述した言語を理解しているものです(理解できない人は、学習者ということになります)。Cで記述したコードは、C++コンパイラで多くの場合正常に処理されます。そのように仕様が決められ、VC++チームはその仕様を実装しているからです。しかし、C++ソースコードをCコンパイラに処理させる経験者はいないと思います。区別できると思います。学習者の場合、処理させることもあると思いますが、いろいろな警告やエラーが出され、そこでさらに勉強することになると思います。
「どのコンパイラ(のモード)で実行形式が作成されたかをソースコードから判別することは難しいですよね?」:ソースコードがCで記述されている場合、おっしゃるように難しいものですが(C++はCのスーパーセットであり、Cを可能な限りサポートする方針で設計されています)、C++の場合、それほど難しくはないと思います。多くの人が言及されているDependency Walkerでも調査できると思います。
なお、CやC++などの歴史や設計思想に興味がおありでしたら、参考ページをご閲覧願えると幸いです。
渋木さん、ご返信ありがとうございました。本欄を訪問されている多数のVC++ユーザの皆様の成長にお役に立てれば幸いです。
失礼いたします。 -
補足です。
渋木宏明 さんからの引用
.NET クラスライブラリの使用の有無」が切り分けのポイントではありません。
「実行の方式」の違いが重要なポイントです。「実行の方式」の違いが具体的に何によって生じるかというと、VC++ の場合はコンパイラオプションによって決定されます。
VC++ コンパイラに /clr オプションを与えると、VC++ コンパイラは CLR 対応の実行形式を作成します。
/clr オプションを与えなかった場合は、旧来の Windows OS 専用の実行形式を作成します。VC++ のプロジェクト設定の「共通言語ランタイムの使用」という項目が /clr オプションを制御します。
Win32 xxx や MFC xxx という .NET 以前から存在するプロジェクトタイプでは、デフォルトで /clr オプションは無効です。
(ただし、ユーザ操作により /clr オプションを有効化することも可能です) -
渋木宏明 さんからの引用
Vertial Machineの考え方と仕掛けが.NETにあるとは思いもよらない新知識となりました。大人の事情もあってでしょうが、はっきり "VM" という言葉を使って説明しているのはあまり見かけませんが、.NET ランタイム(=CLR)が拠り所としている CLI 仕様の根底に流れる考え方は Java VM のそれに通じるものがあります。
「VM=遅い」というイメージを嫌って,Microsoft は VM という言葉を避けているという説もありますが,個人的には別の理由で VM を前面に出してほしくないと思っています.
Virtual Machine という言葉から「どこでも同じように動く」を期待するのなら,本来以下が実現されるべきです.
- 同一のCPUアーキテクチャと速度
- 同一の搭載メモリ量
- 同一の動作タイミング
- 同一の付属デバイス
しかし,CLR は実行系の差異をそこまで隠蔽してくれません.
CPU はそのままの速度で動きますし,SSE/SSE2 などが利用可能なら活用します.結果的に CPU によって浮動小数点数の計算結果が異なりさえします.
メモリについても同様です.まったく同じアプリケーションを実行させた場合ですら,実行環境によって GC が発生するタイミングは異なりますし,同じ環境で再現できるとも限りません.現在の .NET 実行系 (CLR) では,JIT の過程を入念に追いかけることで,従来の Win32 アプリケーションとしてのデバッグ手法やプロファイル手法が適用可能です.つまり,それほど OS と密に結合しているわけではありません.
言い換えれば,dimension さんでもその気になれば CLR を 0 から作り上げて,Windows 環境で動かすことは可能です. -
ヘルプに出てくる,
Native C++ Programs のニュアンスは,Programs that are native to Win32, which are built using C++ language
↑ ↑ │ │
│└─────┘ │
└──────────────────────┘「C++言語を使用して作られる,Win32土着のプログラム」
を省略したものでしょう。
.NET Framework が,
Win32API上に(後から)乗っかって,ラップする形になっているので,
(移住民に対して,先住民(native American)と表現するのと似たロジックで)
.NET Framework を利用しないで,旧来どおり,
Win32APIを直接利用するものをNativeと表現したんでしょう。最初のころは,たしか,
managed に対しての意味で unmanaged と表現されていたと思うんだけど,
「管理されていない」 というニュアンスが嫌だったんで,native にしたんでしょう。
もちろん推測ですけどね。